17

我有一个正在更新到 iOS 6 的 iPhone 应用程序,但该应用程序存在轮换问题。我有一个UITabBarController16 UINavigationCotrollers。大多数子视图可以纵向或横向工作,但其中一些仅纵向。在 iOS 6 中,事情在不应该发生的时候发生了变化。

我尝试子类化 tabBarController 以返回supportedInterfaceOrienations当前 navigationController 的选定 viewController:

- (NSUInteger)supportedInterfaceOrientations{

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

这让我更接近了。视图控制器在可见时不会旋转错位,但如果我处于横向并切换选项卡,即使不支持新选项卡,新选项卡也会处于横向。

理想情况下,应用程序只会位于当前可见视图控制器的支持方向。有任何想法吗?

4

4 回答 4

58

子类化您的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;
}

子类化您的UINavigationController重写这些方法:

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

-(BOOL)shouldAutorotate
{
    return YES;
}

然后在您不想旋转的视图控制器中实现这些方法:

- (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。如果您计划支持默认方向,iPhone 的默认方向是颠倒,那么您不需要做任何其他事情。如果你想支持颠倒或者你不想支持另一个方向,那么你需要在 app delegate 和/或 info.plist 中设置适当的值。

于 2012-09-20T02:48:00.840 回答
5

我遇到了导航堆栈中的一些视图控制器支持所有方向的问题,一些只支持纵向,但UINavigationController正在返回所有应用程序支持的方向,这个小技巧帮助了我。我不确定这是预期的行为还是什么

@implementation UINavigationController (iOS6OrientationFix)

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

@end
于 2012-09-20T11:45:23.170 回答
3

我认为这样的东西更好(作为类别方法)

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

这确保了该方法的实现。如果您不进行此检查并且该方法未实现(如在 iOS5 环境中),则应用程序应该崩溃!

于 2012-10-02T12:15:30.827 回答
0

如果您打算为所有视图控制器启用或禁用旋转,则不需要子类化UINavigationController. 而是使用:

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

在你的AppDelegate.

如果您计划在您的应用程序中支持所有方向,但在父视图控制器(UINavigationController例如堆栈)上支持不同方向,您应该使用

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

fromAppDelegate结合您的父视图控制器中的以下方法。

    - (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 控制呈现的视图控制器的旋转设置,因此您必须以某种方式拦截当前在导航堆栈中的视图控制器。所以这就是我所做的:)。希望有帮助!

于 2013-01-20T00:51:03.753 回答