Подтвердить что ты не робот

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.

4b9b3361

Ответ 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