IOS 6 вращений: поддерживаетсяInterfaceOrientations не работает?
У меня возникла проблема с iOS 6 SDK: у меня есть некоторые представления, которые нужно разрешить вращаться (например, видеовизу), а некоторые из них не нужны.
Теперь я понимаю, что мне нужно проверить все ориентации в Info.plist приложения, а затем разобраться в каждом ViewController, что должно произойти. Но это не работает! Приложение всегда поворачивается к ориентациям, которые указаны в Info.plist.
Info.plist:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
любой ViewController, который не должен вращаться:
//deprecated
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
Наблюдение: приложение поворачивается к пейзажной и портретной ориентации. Любые идеи, почему или что я делаю неправильно?
Cheers,
Марк
Изменить: мои последние результаты также показывают, что если вы хотите иметь поворот в какой-то момент вашего приложения, вам нужно активировать все четыре направления вращения в настройках вашего проекта или Info.plist. Альтернативой этому является переопределение
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
в AppDelegate, который переопределяет Info.plist. Невозможно больше установить только портрет в вашем Info.plist, а затем иметь поворот в каком-либо ViewController, переопределив shouldAutorotateToInterfaceOrientation или supportedInterfaceOrientations.
Ответы
Ответ 1
Если ваш ViewController является дочерним элементом UINavigationController или UITabBarController, то это ваша проблема. Возможно, вам потребуется подкласс этого родительского контроллера представления, просто переопределив эти методы InterfaceOrientation, как вы показали в своем вопросе
EDIT:
Пример только для портрета TabBarController
@interface MyTabBarController : UITabBarController
{
}
@end
@implementation MyTabBarController
// put your shouldAutorotateToInterfaceOrientation and other overrides here
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
@end
Ответ 2
Добавляя к ответу CSmith выше, следующий код в подклассе UINavigationController позволяет делегировать диспетчеру верхнего уровня так, как я ожидал, что это будет работать в первую очередь:
- (BOOL)shouldAutorotate;
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([[self topViewController] respondsToSelector:@selector(supportedInterfaceOrientations)])
return [[self topViewController] supportedInterfaceOrientations];
else
return [super supportedInterfaceOrientations];
}
Ответ 3
Здесь другая альтернатива подходу CSmith.
Если вы хотите реплицировать поведение pre-iOS 6, когда все представления в стеке/вкладке навигации должны согласовать допустимый набор ориентаций, поместите это в свой подкласс UITabBarController
или UINavigationController
:
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger orientations = [super supportedInterfaceOrientations];
for (UIViewController *controller in self.viewControllers)
orientations = orientations & [controller supportedInterfaceOrientations];
return orientations;
}
Ответ 4
Попробуйте добавить эту категорию:
@interface UINavigationController(InterfaceOrientation)
@end
@implementation UINavigationController(InterfaceOrientation)
- (NSUInteger) supportedInterfaceOrientations {
if (self.viewControllers.count > 0)
return [[self.viewControllers objectAtIndex:0] supportedInterfaceOrientations];
else
return UIInterfaceOrientationMaskAll;
}
@end
Ответ 5
Дальнейшее дополнение к @CSmith и @EvanSchoenberg.
Если у вас есть некоторые виды, которые вращаются, а некоторые виды, которые этого не делают, вы должны создать собственный экземпляр UITabBarController
, но все же пусть каждый UIViewController
принимает решение.
- (BOOL)shouldAutorotate;
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
UIViewController * top;
UIViewController * tab = self.selectedViewController;
if([tab isKindOfClass:
([UINavigationController class])]) {
top = [((UINavigationController *)tab)
topViewController];
}
if ([top respondsToSelector:@selector(supportedInterfaceOrientations)])
return [top supportedInterfaceOrientations];
else
return [super supportedInterfaceOrientations];
}
Ответ 6
Для пользователей, использующих UINavigationController и Swift, вы можете добавить это расширение в свой проект. После этого навигационные контроллеры делегируют управление их дочернему контроллеру.
extension UINavigationController {
override public func supportedInterfaceOrientations()
-> UIInterfaceOrientationMask {
if let ctrl = topViewController {
return ctrl.supportedInterfaceOrientations()
}
return super.supportedInterfaceOrientations()
}
override public func shouldAutorotate() -> Bool {
if let ctrl = topViewController {
return ctrl.shouldAutorotate()
}
return super.shouldAutorotate()
}
}
Ответ 7
@Ответ Шимански Артема хорош, но я думаю, что использование самого верхнего (в настоящее время видимого) контроллера - лучшее решение:
@interface UINavigationController(InterfaceOrientation)
@end
@implementation UINavigationController(InterfaceOrientation)
- (NSUInteger) supportedInterfaceOrientations {
if (self.viewControllers.count > 0){
return [[self.viewControllers objectAtIndex:[self.viewControllers count] - 1] supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskAll;
}
@end
Ответ 8
В качестве альтернативного варианта, если вы хотите сохранить функциональность вращения перед iOS6 в своем приложении:
Здесь полезный бит кода в github, который swizzly метод вызывает iOS6, так что ротация работает так же, как на iOS4/iOS4. Это действительно помогло мне, так как я поддерживаю устаревшее приложение, которое действительно управляет поворотами. Было бы очень много работы по внедрению изменений, необходимых для iOS6. Престижность пользователю, который его разместил.
https://gist.github.com/3725118