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

IOS 6 UITabBarController поддерживает ориентацию с текущим контроллером UINavigation

У меня есть приложение для iPhone, которое я обновляю до iOS 6, у которого есть проблемы с ротацией. У меня есть UITabBarController с 16 UINavigationCotrollers. Большинство подзонов могут работать в портретной или альбомной ориентации, но некоторые из них - только портрет. С iOS 6 вещи вращаются, когда они не должны.

Я попытался подклассифицировать tabBarController, чтобы вернуть supportedInterfaceOrienations текущего выбранного ControlController navigationController:

- (NSUInteger)supportedInterfaceOrientations{

    UINavigationController *navController = (UINavigationController *)self.selectedViewController;
    return [navController.visibleViewController supportedInterfaceOrientations];
}

Это приблизило меня. Контроллер просмотра не будет вращаться вне позиции, когда он будет видимым, но если я нахожусь в альбомной ориентации и переключаю вкладки, новая вкладка будет в ландшафте, даже если она не поддерживается.

В идеале приложение будет находиться только в поддерживаемой ориентации текущего видимого контроллера. Любые идеи?

4b9b3361

Ответ 1

Подкласс your UITabBarController переопределяет эти методы:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // You do not need this method if you are not supporting earlier iOS Versions
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [self.selectedViewController supportedInterfaceOrientations];
}

-(BOOL)shouldAutorotate
{
    return YES;
}

Подкласс your UINavigationController переопределяет эти методы:

-(NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations];
}

-(BOOL)shouldAutorotate
{
    return YES;
}

Затем реализуйте эти методы в вашем viewControllers, которые вы не хотите вращать:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

И для просмотраКонтроллеры, которые вы хотите повернуть:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    }

    -(NSUInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }

    -(BOOL)shouldAutorotate
    {
        return YES;
    }

Ваш tabbarController должен быть добавлен как RootviewController окна приложения. Если вы планируете поддерживать ориентацию по умолчанию, все, кроме upsidedown, по умолчанию для iPhone, тогда вам не нужно ничего делать. Если вы хотите поддерживать перевернутый или если вы не хотите поддерживать другую ориентацию, вам необходимо установить соответствующие значения в делегате приложения и/или info.plist.

Ответ 2

У меня возникла проблема, что некоторые контроллеры View в стеке навигации поддерживают все ориентации, некоторые только портреты, но UINavigationController возвращает все поддерживаемые приложениями ориентации, этот маленький взлом помог мне. Я не уверен, что это предполагаемое поведение или что

@implementation UINavigationController (iOS6OrientationFix)

-(NSUInteger) supportedInterfaceOrientations {
    return [self.topViewController supportedInterfaceOrientations];
}

@end

Ответ 3

Я думаю, что лучше что-то вроде этого (как метод категории)

-(NSUInteger) supportedInterfaceOrientations {
    if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientations)])
    {
        return [self.topViewController supportedInterfaceOrientations];
    }
    return UIInterfaceOrientationMaskPortrait;
}

это гарантирует, что метод будет реализован. Если вы не выполняете эту проверку, и метод не реализован (например, в iOS5 env), приложение должно сработать!

Ответ 4

Если вы планируете включать или отключать вращение для всех контроллеров представления, вам не нужно подклассы UINavigationController. Вместо этого используйте:

   -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

в AppDelegate.

Если вы планируете поддерживать все ориентации в своем приложении, но разные ориентации на контроллерах PARENT View (например, UINavigationController), вы должны использовать

   -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

из AppDelegate в сочетании со следующими способами в вашем контроллере просмотра PARENT.

    - (BOOL)shouldAutorotate

и

- (NSUInteger)supportedInterfaceOrientations

Но если вы планируете иметь разные настройки ориентации в разных CHILDREN ViewControllers в том же стеке навигации (например, я), вам нужно проверить текущий ViewController в стеке навигации.

В моем подклассе UINavigationController я создал следующее:

    - (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    int interfaceOrientation = 0;

    if (self.viewControllers.count > 0)
    {
        DLog(@"%@", self.viewControllers);
        for (id viewController in self.viewControllers)
        {
            if ([viewController isKindOfClass:([InitialUseViewController class])])
            {
                 interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
            }
            else if ([viewController isKindOfClass:([MainViewController class])])
            {
                 interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
            }
            else
            {
                 interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown;
            }
        }
    }
    return interfaceOrientation;
}

Поскольку вы больше не можете контролировать с помощью ViewControllers детей параметры поворота представленного контроллера представлений, вы должны каким-то образом перехватить какой контроллер просмотра в настоящее время находится в стеке навигации. Так вот что я сделал:). Надеюсь, что это поможет!