Я уже проголосовал до ответа на @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;
Ваш ответ очень помогает. Теперь все, что я должен проверить, это если isPortrait истинно, вместо того, чтобы пытаться добавить код ориентации в методы вращения viewController – Justin
Имейте в виду, что это не всегда работает. В частности, если ваш контроллер является первым в вашем приложении. В моих симуляторах тесты [self interfaceOrientation] всегда возвращаются как 1. Может быть, это на самом деле другое на самом устройстве .. по крайней мере .. трудно проверить. –
Я верю, что при первом запуске приложения ориентация по умолчанию - портрет. Это может объяснить, почему [self interfaceOrientation] всегда возвращает 1. –