【问题标题】:Does a TabBar application need shouldAutorotateToInterfaceOrientation to be returning YES on all of its viewControllers?TabBar 应用程序是否需要 shouldAutorotateToInterfaceOrientation 在其所有视图控制器上返回 YES?
【发布时间】:2011-12-06 17:50:33
【问题描述】:

我正在开发一个以 TabBarController 作为根控制器的 iphone 应用程序。这个根控制器与导航控制器相关联(每个控制器都与特定的标签栏按钮相关)。

这些导航控制器上的一个显示了一些照片,因此我需要启用 Lanscape,这显然在我将此代码添加到所有视图控制器之前不起作用

- (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)toInterfaceOrientation
{
    return YES;
}

但是,现在在所有视图中都启用了所有方向,我不想在横向中显示一些视图非常难看:(

知道如何仅在此照片视图上保留横向方向并在所有其他视图上禁用它吗?

【问题讨论】:

    标签: iphone ios uiviewcontroller uinavigationcontroller uitabbarcontroller


    【解决方案1】:

    考虑以模态方式显示需要完全重定向功能的 UIViewController。 这将是处理这种情况的常见且在我看来是正确的方法。

    简短地回答您的主题:是的,如果您希望任何选项卡式视图控制器允许重新定向,它确实必须返回 YES。 UINavigationControllers 堆栈中的视图控制器也是如此。因此,它们的任意组合也是如此。

    来自 Apple 关于该主题的技术说明:

    为什么我的 UIViewController 不随设备旋转?

    UITabBarController 中的所有子视图控制器或 UINavigationController 不同意共同的方向集。到 确保您的所有子视图控制器正确旋转,您 必须为每个视图实现 shouldAutorotateToInterfaceOrientation 表示每个选项卡或导航级别的控制器。每个人都必须同意 在相同的方向上旋转发生。也就是说,他们都 对于相同的方向位置,应该返回 YES。

    如果您无法选择使用模态呈现的视图控制器 - 这是另一种方式...

    还有一个解决方案可能看起来有点“hacky”,但过去对我有用。我将以一种非常“hacky”的方式起草它以简化答案。

    在所有视图控制器的 shouldAutorotateToInterfaceOrientation:toInterfaceOrientation 实现中,返回一个全局值。根据当前显示的 viewController 的需要更改该全局值。尽管有人说 viewController 只被问过一次,但这个常见的谣言对我来说是不真实的。所以这里是超级黑客;

    导航堆栈中的所有视图控制器都应该像这样实现 shouldAutorotate 方法:

    - (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)toInterfaceOrientation
    {
        extern BOOL gSouldAutorotateToAnyOrientationFlag;
        if (gShouldAutorotateToAnyOrientationFlag)
        {
            return YES;
        }
        return UIInterfaceOrientationIsPortrait(toInterfaceOrientation);   
    }
    

    现在,在您的应用程序的某个地方,您应该声明并实例化该全局标志 - 您可以将这个丑陋的全局标志放在您的应用程序委托实现中,直接在导入下方和 @implementation 块上方:

    BOOL gShouldAutorotateToAnyOrientationFlag = NO;
    

    在所有应该仅以纵向模式显示的 viewController 中,将该标志设置为 NO - 例如在 viewWillAppear 内;

    - (void)viewWillAppear:(BOOL)animated
    {
        extern BOOL gShouldAutorotateToAnyOrientationFlag;
        gShouldAutorotateToAnyOrientationFlag = NO;   
    }
    

    在应该以任何方向显示的 viewController/s 中,将该标志设置为 YES - 再次在 viewWillAppear 中;

    - (void)viewWillAppear:(BOOL)animated
    {
        extern BOOL gShouldAutorotateToAnyOrientationFlag;
        gShouldAutorotateToAnyOrientationFlag = YES;   
    }
    

    这样,每当询问整个导航堆栈的定位功能时,都会给出正确的答案。根据我的经验,会一遍又一遍地询问整个堆栈,并且不会缓存答案,因此我的 hack 可以在我需要的时候工作。尽管如此,谣言似乎很普遍,即这些答案以某种方式被缓存,因此该谣言在某些情况下可能是有效的 - 因此,如果这对您不起作用(甚至被否决:D),我将不承担任何责任

    【讨论】:

    • 我在哪里可以声明这个全局变量(BOOL shouldAutorotateToAnyOrientationFlag)
    • 任何地方 - 例如在您的应用程序代理之上(呃,我是否只是建议使用应用程序代理进行此黑客攻击?:D)。注意它不应该被声明为类实例变量,因此需要在类实现之外声明。
    • 喜欢在 .h 文件的顶部吗? @interface 声明之前的某个地方?
    • 不,在实现文件 (.m) 的顶部 - 直接在您的导入下方将是一个不错且常见的地方。
    【解决方案2】:

    在您只想要横向的视图上:

    - (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)toInterfaceOrientation
    {
        return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
    }
    

    如果更适合您的需要,您可以将 UIInterfaceOrientationIsLandscape 替换为 UIInterfaceOrientationIsPortrait。

    【讨论】:

    • 如果其中任何一个在 UITabBarController 的任何 UINavigationController 的导航堆栈中,则不会工作。 (请注意,我没有投反对票,因为这个答案并不完全错误)
    猜你喜欢
    • 2015-07-24
    • 2012-10-19
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多