Определить UIInterfaceOrientation на iPad - PullRequest
35 голосов
/ 10 апреля 2010

Мне не нужно указывать ориентацию в этом случае, мне просто нужно определить ее, но у меня проблемы. У меня есть условный код, который должен работать только в портретной ориентации, и если устройство находится в альбомной ориентации, мне нужно сделать что-то еще. Так как deviceOrientation не обязательно совпадает с interfaceOrientation, я не могу найти способ протестировать портретный режим.

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

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

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

Ответы [ 10 ]

77 голосов
/ 10 апреля 2010

Вам известно о свойстве interfaceOrientation класса UIViewController?

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

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

40 голосов
/ 21 мая 2010

Особенно при запуске я обнаружил, что следующее является всегда точным для пользовательского интерфейса, независимо от того, что говорит UIDevice ориентация.

[UIApplication sharedApplication].statusBarOrientation
10 голосов
/ 01 апреля 2011

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

Однако [UIApplication sharedApplication].statusBarOrientation всегда надежен. Вы сэкономили мне много времени слизнюка. Спасибо.

4 голосов
/ 12 января 2012
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

if ((orientation == UIInterfaceOrientationLandscapeLeft)
||  (orientation == UIInterfaceOrientationLandscapeRight) )
{
    //Landscape
}
else
{
    //Portrait
}
1 голос
/ 11 июля 2016

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

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

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

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

[UIApplication sharedApplication].statusBarOrientation

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

Возьмите этот пример:

  • У меня есть приложение, которое поддерживает ВСЕ интерфейсы, и контроллер корневого представления, который также поддерживает их.
  • Теперь я представляю UIViewController, в результате чего ориентация строки состояния станет альбомной.
  • Какая альбомная ориентация (влево или вправо) зависит от того, что возвращает preferredInterfaceOrientationForPresentation для этого контроллера представления, какова текущая ориентация устройства и какие ориентации интерфейса поддерживает контроллер представления (см. Следующий пункт).
  • Строка состояния переместится в альбомную ориентацию независимо от текущей ориентации устройства, поскольку этот контроллер представления поддерживает только альбомную ориентацию на основе того, что возвращает supportedInterfaceOrientations. Допустим, мы поддерживаем как левый, так и правый ландшафт с UIInterfaceOrientationMaskLandscape.
  • Я также хочу условно анимировать этот контроллер вида в положение с преобразованием вращения . Это будет необходимо только при переходе от портрета или портрета вверх ногами к левому или правому пейзажу. В противном случае это будет более простая презентация без вращения.
  • Затем, через некоторое время и использование устройства, я отклонил этот контроллер представления.
  • Теперь я хочу условно анимировать этот контроллер вида с экрана с помощью другого преобразования вращения . Это будет необходимо только при переходе от пейзажа влево или пейзажа вправо к портрету или портрету вверх ногами. В противном случае это будет более простая анимация увольнения без поворота.
  • На этом этапе ориентация строки состояния станет такой, какой система сочтет подходящей для комбинации предпочтительной ориентации интерфейса вашего корневого контроллера и поддерживаемых ориентаций интерфейса, а также текущей UIDeviceOrientation.
  • Поскольку контроллер представления, который мы собираемся поддерживать ВСЕХ ориентаций интерфейса, если ориентация вашего устройства - FaceUp или FaceDown, вы не можете надежно угадать следующий 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(nonatomic,readonly) NSTimeInterval statusBarOrientationAnimationDuration;
1 голос
/ 16 сентября 2014
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{</br>
   if (UIDeviceOrientationIsLandscape(toInterfaceOrientation)) {</br>
        some instructions;
   } else { 
        some instructions;
   }
}

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

1 голос
/ 01 мая 2014

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

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

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

1 голос
/ 24 августа 2012
    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 голос
/ 12 марта 2012

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

0 голосов
/ 30 сентября 2015

Начиная с iOS8, API устарели или возвращают бесполезные результаты, такие как .FaceUp .FaceDown

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

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

...