2010-04-10 3 views
34

Мне не нужно указывать ориентацию в этом случае, мне просто нужно ее обнаружить, но у меня проблемы. У меня есть условный код, который должен работать только в портрете, и если устройство в ландшафте, мне нужно сделать что-то еще. Поскольку deviceOrientation не обязательно совпадает с интерфейсом, я не могу найти способ проверить портретный режим.Определить UIInterfaceOrientation на iPad

Большинство учебных пособий, которые я нахожу в Google, - это способы заставить пейзаж или сделать какой-то поворот. Единственное, что я хочу сделать, это определить, что такое ориентация. Вот мой код, который не работает:

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    //currentOrientation is declared as UIInterfaceOrientation currentOrientation 
    currentOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 
NSLog(@"%@",currentOrientation); // == NULL 
} 

нужно определить значение interfaceOrientation и программы условно. Спасибо за вашу помощь!

ответ

78

Ты знаешь о собственности interfaceOrientation класса UIViewController?

- (void) viewDidLoad { 
    [super viewDidLoad]; 
    BOOL isPortrait = UIDeviceOrientationIsPortrait(self.interfaceOrientation); 
    // now do whatever you need 
} 

Или вы после [[UIDevice currentDevice] orientation]?

+0

Ваш ответ очень помогает. Теперь все, что я должен проверить, это если isPortrait истинно, вместо того, чтобы пытаться добавить код ориентации в методы вращения viewController – Justin

+2

Имейте в виду, что это не всегда работает. В частности, если ваш контроллер является первым в вашем приложении. В моих симуляторах тесты [self interfaceOrientation] всегда возвращаются как 1. Может быть, это на самом деле другое на самом устройстве .. по крайней мере .. трудно проверить. –

+0

Я верю, что при первом запуске приложения ориентация по умолчанию - портрет. Это может объяснить, почему [self interfaceOrientation] всегда возвращает 1. –

39

В частности, при запуске я нашел для UI всегда точный результат, независимо от того, что UIDevice говорит о ориентации.

[UIApplication sharedApplication].statusBarOrientation 
+0

Ум, разве это не совсем то же самое в исходном вопросе? Я обнаружил в своих тестах, что он всегда возвращает 1, когда приложение включено, и поэтому бесполезно. –

+0

@ Матт, я думаю, ты прав. Не знаю, почему я отправил это обратно в май, он действительно выглядит так же, как и исходный. Возможно, я неправильно понял этот вопрос, поскольку я использовал вышеуказанное, когда ориентация устройства неизвестна, лицевой стороной вверх или вниз. – slycrel

+0

Удивительный, действительно надежный на сим. Благодаря! –

10

self.interfaceOrientation ненадежный в определенных ситуациях. Например, повторная компоновка вкладок в приложении табуляции возвращает неверное значение.

Однако [UIApplication sharedApplication].statusBarOrientation всегда надежно. Ты спас меня много времени. Спасибо.

+2

Возможно, стоит отметить, что ** не ** безопасно принимать статусBarOrientation действует на ранней стадии исполнения. Похоже, что это значение обновляется после выхода didFinishLaunchingWithOptions. Это использование симулятора iOS 4.3. –

4
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 

if ((orientation == UIInterfaceOrientationLandscapeLeft) 
|| (orientation == UIInterfaceOrientationLandscapeRight)) 
{ 
    //Landscape 
} 
else 
{ 
    //Portrait 
} 
+1

aka UIInterfaceOrientationIsLandscape() –

1

Я знаю, что это очень старый пост. Как бы то ни было, я хотел бы добавить пункт, чтобы сказать, что лучше лучше проверить ориентацию строки состояния. Когда вы звоните self.interfaceorientation, он звонит shouldRotateToOrientation каждый раз. Если вы написали какой-то код в этом методе, он будет выполнен. Поэтому будьте осторожны!

1
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; 
    UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation; 

    if(deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown){ 
     if(debug){ 
      NSLog(@"Nothing to change because it is gone to Flat"); 
     } 
     return; 
    } 
    if(deviceOrientation !=statusBarOrientation){ 
     if(debug){ 
      NSLog(@"\nApple has a bug?:\n UIDeviceOrientation : %d, UIInterfaceOrientation: %d",deviceOrientation, statusBarOrientation ); 
     } 
    } 

Вы не поверите мне, пока не увидите на консоли второй выход! Некоторые ситуации - и они существуют! - отображается последний контент NSLog!

Чем вы должны обходиться, так как у iOS нет ошибок, удачи всем!

Ах, что ... модератор форума, возможно, удалит это сообщение, потому что это не значит быть и отвечать по его мнению!

Я надеюсь, что это помогает кому-то когда-то, что происходит на Iphone тоже ... (там я получил)

1

Смешайте его немного:

BOOL isLandscape = self.view.frame.size.width > self.view.frame.size.height; 

(редактировать) Очевидно, что предыдущие ответы правильный способ сделать это, и это решение потерпит неудачу в ситуации, когда контроллеры представлений не являются полноэкранными.

1
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{</br> 
    if (UIDeviceOrientationIsLandscape(toInterfaceOrientation)) {</br> 
     some instructions; 
    } else { 
     some instructions; 
    } 
} 

Это фрагмент из одной из моих программ. Конечно, вы можете использовать оператор if в своем уведомлении ViewDidLoad.

0

По iOS8, API-интерфейсы Устаревшие или возвращающие бесполезные результаты, такие как .FaceUp.FaceDown

Это потому, что компания Apple не хочет, чтобы вы, чтобы обновить пользовательский интерфейс с помощью ориентации, а с помощью классов размера, ограничения и пропорции (используя n% от супервизора).

Действительно, ориентация зависимый код может не в состоянии обеспечить хорошие результаты по всему диапазону устройства и прецедент (особенно многозадачность)

0

Я уже проголосовал до ответа на @slycrel, но я хотел бы взять время написать это и указать некоторые вещи, которые, кажется, теряются в этом старом вопросе и множество других вопросов по этому вопросу.

Это правда, что Apple действительно не хочет, чтобы мы обновили большую часть нашего пользовательского интерфейса на основе изменений ориентации, но это все еще возможно, а иногда и необходимо в каждом конкретном случае, и так будет, пока Apple не улучшит их новые (МОГ) интерфейсы (например viewWillTransitionToFrame: будет намного больше пользы, чем viewWillTransitionToSize:. Просто говорю)

Почему я голосовал до ответа на @slycrel связано с тем, что вы должны иметь в виду, как логическое различие между UIDeviceOrientation и UIInterfaceOrientation.

Эта строка состояния - это то, что обозначает известное в настоящее время приложение UIInterfaceOrientation. Все это около FaceUp, FaceDown связано только с ориентацией устройства, не обязательно с вашим приложением. Приложение не поддерживает ориентации устройств в любом случае. Действительно, UIDeviceOrientation можно полностью игнорировать, если все, что вам нужно сделать, это обеспечить правильную компоновку и анимацию вещей в вашем интерфейсе, что составляет 99% случаев использования приложения для разработчиков приложений. В настоящее время это достигается с ответом строки состояния UIInterfaceOrientation от @ slycrel в:

[UIApplication sharedApplication].statusBarOrientation 

Следует отметить, версия этого свойства ReadWrite устарела, версия чтения нет.

Возьмем такой пример:

  • У меня есть приложение, которое поддерживает все интерфейсы ориентации, и контроллер представления корень, который поддерживает их.
  • Теперь я представляю UIViewController, что приведет к тому, что ориентация состояния станет ландшафтом.
  • Какая ландшафтная ориентация (левая или правая), в которой она идет, основана на том, что возвращается preferredInterfaceOrientationForPresentation для этого контроллера представления, какова текущая ориентация устройства и какие ориентации интерфейса поддерживается контроллером представления (см. Следующую точку).
  • Строка состояния будет идти в ландшафт, независимо от ориентации текущего устройства, поскольку этот контроллер просмотра поддерживает только пейзаж, основанный на том, что возвращается supportedInterfaceOrientations. Допустим, мы поддерживаем оба пейзажа слева и справа с UIInterfaceOrientationMaskLandscape.
  • Я также хочу условно анимировать этот контроллер вида в положение с преобразованием поворота.Это будет необходимо только при переходе от портрета или портрета вверх дном, к пейзажному левому или ландшафтному праву. В противном случае это будет более простая анимация презентации без вращения.
  • Затем, после некоторого времени и использования устройства, я отклоняю этот контроллер.
  • Теперь я хочу условно анимировать этот контроллер вида с экрана с другим преобразованием поворота. Это будет необходимо только при переходе с пейзажа влево или вправо, на портрет или портрет вверх ногами. В противном случае это будет более простая анимация увольнения без вращения.
  • На этом этапе ориентация панели состояния станет тем, что решает система, подходит для комбинации предпочтительной ориентации интерфейса контроллера корневого представления и поддерживаемых ориентаций интерфейса, а также текущего UIDeviceOrientation устройства.
  • Поскольку контроллер представления мы будем поддерживает все ориентации интерфейса, если ориентация вашего устройства является лицевой стороной вверх или лицевой стороной вниз, вы не можете надежно угадать следующий UIInterfaceOrientation основанный на UIDeviceOrientation, и вам не придется в любом случае.
  • Итак ... ориентация состояния на помощь!

Предыдущий пример возможен, поскольку ориентация строки состояния не обновляется, когда начинается переход к контроллеру представления (система запрашивает делегат перехода для аниматора и т. Д.). Затем он обновляется, когда переход начинает анимацию (например, к моменту, когда вызывается animationTransition:). Таким образом, вы должны иметь хорошее сравнение, используя только начальные и текущие значения строки состояния UIInterfaceOrientation.

Даже без использования переходов контроллера просмотра, все равно будет безопасно обновлять представления в зависимости от ориентации строки состояния.

Имейте в виду, если вы вручную обновляете строку состояния, и если вы не используете «Просмотр строки состояния на основе контроллера» в вашем Info.plist, тогда логика вашего приложения должна знать, когда статус бар изменит ориентацию. Вы, вероятно, будете искать пару NSNotification имен для этих случаев, а именно:

  • UIApplicationWillChangeStatusBarOrientationNotification
  • UIApplicationDidChangeStatusBarOrientationNotification

, а также данные UIApplicationDelegate методов:

- (void)application:(UIApplication *)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration; 
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation; 
- (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window 

И это другое полезное UIApplication property:

@property(nonatomic,readonly) NSTimeInterval statusBarOrientationAnimationDuration; 
Смежные вопросы