Определить UIInterfaceOrientation на iPad

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

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

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

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


person Justin    schedule 10.04.2010    source источник


Ответы (10)


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

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

Или вам нужен [[UIDevice currentDevice] orientation]?

person zoul    schedule 10.04.2010
comment
Ваш ответ очень помогает. Теперь все, что мне нужно проверить, это истинность isPortrait вместо попытки добавить код ориентации в методы вращения viewController. - person Justin; 11.04.2010
comment
Имейте в виду, что это не всегда работает. В частности, если ваш контроллер является первым в вашем приложении. В моих тестах на симуляторе [self interfaceOrientation] всегда возвращается как 1. Может быть, на реальном устройстве все по-другому ... по крайней мере ... трудно проверить. - person M. Ryan; 15.04.2010
comment
Я считаю, что при первом запуске приложения ориентация по умолчанию - портретная. Это может объяснить, почему [self interfaceOrientation] всегда возвращает 1. - person Joo Park; 03.06.2010
comment
@zoul, значение isPortrait bool возвращает мне ДА в симуляторе. У меня нет устройства iPad, тогда как я могу определить текущую ориентацию устройства в viewDidLoad? - person Tirth; 29.07.2010
comment
это не работает с detailViewController внутри разделенного представления ... isPortrait всегда ДА. Любые идеи? - person Artilheiro; 15.08.2010
comment
Я сам столкнулся с этой проблемой. Конечная причина в том, что self.interfaceOrientation равно NULL при первоначальной загрузке представления, так что и UIDeviceOrientationIsPortrait, и UIDeviceOrientationIsLandscape возвращают NO. Использование [UIApplication sharedApplication].statusBarOrientation в ответе ниже всегда работает правильно, поскольку эта ориентация никогда не имеет значения NULL. - person MusiGenesis; 09.06.2011
comment
@MusiGenesis: неправда, как уже упоминали другие: часто (в моем случае всегда) 1 (портрет) при запуске приложения. Нет никакой разницы между interfaceOrientation в вашем (первом) контроллере представления или [UIApplication sharedApplication]. Это действительно сложно, а то и невозможно узнать ориентацию пользовательского интерфейса при запуске (ориентация устройства ничего не говорит вам, когда оно обращено вверх или вниз). - person zmippie; 11.06.2011
comment
@zmippie: что не так, что self.interfaceOrientation имеет значение NULL при начальной загрузке или что statusBarOrientation никогда не имеет значения NULL? И то, и другое верно для меня. - person MusiGenesis; 12.06.2011
comment
Мне не нравится использовать UIDeviceOrientation для ориентации, поскольку, когда он находится лицом вверх / вниз, он более или менее бесполезен, если вы пытаетесь определить, находится ли ваше приложение в альбомной или портретной ориентации. Изначально это вызывало ошибку в моем коде, пока я не переключился на использование [UIApplication sharedApplication].statusBarOrientation. Однако я не пытался ориентироваться во время запуска ... Только мои мысли по этому поводу. - person Sam; 31.10.2011
comment
используйте ориентацию [[UIDevice currentDevice]] в viewDidLoad - person AP inc.; 02.03.2012
comment
Если вы собираетесь проверить self.interfaceOrientation, вам нужно использовать UIInterfaceOrientationIsPortrait () вместо UIDeviceOrientationIsPortrait (). - person ToddH; 24.10.2012
comment
interfaceOrientation впервые устарел в iOS 8.0 - person barfoon; 03.09.2014

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

[UIApplication sharedApplication].statusBarOrientation
person slycrel    schedule 21.05.2010
comment
Гм, разве это не то же самое в исходном вопросе? В своих тестах я обнаружил, что он всегда возвращает 1 при запуске приложения и поэтому довольно бесполезен. - person Matt Rix; 28.11.2010
comment
@ Мэтт, я думаю, ты прав. Понятия не имею, почему я опубликовал это в мае, он действительно выглядит так, как будто это тот же код, что и оригинал. Возможно, я неправильно понял вопрос, поскольку использовал вышеупомянутое, когда ориентация устройства неизвестна, лицом вверх или вниз. - person slycrel; 30.11.2010
comment
Круто, действительно надежно на симе. Спасибо! - person Sam Stewart; 04.01.2011
comment
это очень полезно для меня, потому что при первом запуске UIInterfaceOrientation Ориентация = (UIInterfaceOrientation) [UIDevice currentDevice] .orientation; всегда возвращать 0. даже если это портрет. - person KDeogharkar; 22.04.2013
comment
К сожалению, это неплохое решение устарело в iOS 9. - person Jerry Chen; 12.08.2016

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

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

person Devang Vyas    schedule 01.04.2011
comment
Возможно, стоит отметить, что предположить, что statusBarOrientation действителен на раннем этапе выполнения, небезопасно. Кажется, что это значение обновляется после выхода didFinishLaunchingWithOptions. Это с помощью симулятора iOS 4.3. - person doc taco; 29.08.2011

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

person Vignesh    schedule 12.03.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 тоже бывает ... (вот и попал)

person Community    schedule 24.08.2012

Немного перемешиваем:

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

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

person Adam Eisfeld    schedule 30.04.2014

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

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

person crash    schedule 16.09.2014

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

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

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

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

[UIApplication sharedApplication].statusBarOrientation

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

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

  • У меня есть приложение, которое поддерживает ВСЕ ориентации интерфейсов, а также контроллер корневого представления, который их поддерживает.
  • Теперь я представляю 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;
person drkibitz    schedule 11.07.2016

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

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

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

person Antzi    schedule 30.09.2015
comment
Иногда требуется ориентация устройства для поворота входа камеры - person rockdaswift; 08.01.2019

person    schedule
comment
он же UIInterfaceOrientationIsLandscape () - person Chris Conover; 02.02.2016