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