Я уже проголосовал за ответ @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;