【问题标题】:Selective Autorotation within a UINavigationController and UITabBarControllerUINavigationController 和 UITabBarController 中的选择性自动旋转
【发布时间】:2010-11-14 20:51:14
【问题描述】:

您好!这是场景。

从导航控制器开始(并且不存在标签栏 - 它从先前的视图控制器推送中隐藏),我初始化一个新的视图控制器并将其推送到导航控制器堆栈上。这个新的 VC 包含一个孤独的 UIView,我以编程方式在其中添加一个具有相同框架的 UIScrollView。 (我想避免 UIView,但这是我可以将 self.view 分配给某些东西的唯一方法。我怀疑投射 UIScrollView UIView 中的 viewDidLoad 是不可取的。)

所以现在我们有了一个导航栏和一个滚动视图。我已经将它设置为滚动浏览一些图像(我知道,这让我大吃一惊!),效果很好。现在我希望它支持自动旋转。所以我在 VC 中这样回应:

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

编译并运行。啊……什么都没有。显然我做错了什么。

现在,我已经阅读了有关 UINavigationController and autorotation 的帖子,并且我偷偷怀疑我的做法是错误的,并且使事情变得比必要的复杂。

必须有更好的方法来呈现支持自动旋转的 UIScrollView。也许导航控制器挡住了路,但我不知道如何绕过它。

理想情况下,我想要不显示任何导航栏的东西。相反,我们有一个从顶部显示/隐藏的工具栏/状态栏(就像您在播放视频时看到的那样)。如果导航栏必须保留 - 或者如果这真的是我在播放视频与工具栏时看到的较短高度的导航栏,但是我可以旋转吗?问题是,我只希望它在查看像素时以这种特定模式旋转。其他时间都没有。

我敢尝试使用模态VC吗? (Yeccch - 不,这也不对。而且它还有一个导航栏。)

【问题讨论】:

标签: iphone uinavigationcontroller uiscrollview uitabbarcontroller rotation


【解决方案1】:

还可以更简单:

1) 子类UITabBarController 并按照您的描述实现shouldAutorotate...(第二个代码sn-p)

2) 更改您的xxxAppDelegate.h 以将UITabBarController 的类更改为您刚刚创建的子类。 (使用#import YourNewTabBarController.h)

3) 在MainWindow.xib 中将标签栏控制器的类更改为您的新类。

快!

PS:YourNewTabBarController 应该只实现shouldAutoRotate.... 删除所有其他(自动生成的)内容。

【讨论】:

    【解决方案2】:

    您可以通过创建 UITabBarController 类别来解决此问题,而无需子类化。

    这是处理我的情况的类别实现,其中我有与我的选项卡关联的匿名 UINavigationControllers 和自定义 UIViewController 子类作为 UINavigationControllers 的根视图控制器:

    @implementation UITabBarController (Rotation)
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
    {   
        if ([self.selectedViewController isKindOfClass:[UINavigationController class]]) {
            UIViewController *rootController = [((UINavigationController *)self.selectedViewController).viewControllers objectAtIndex:0];
            return [rootController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
        }
        return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
    }
    
    @end
    

    我在 UINavigationController 上还有一个类别,默认返回 YES。因此,默认行为是启用旋转,我可以从 shouldAutorotateToInterfaceOrientation:interfaceOrientation 返回 NO,仅针对我希望禁用旋转的控制器和方向。

    【讨论】:

    • 太棒了!类别干净多了,两个串联使用更甜。
    • 太好了,但我对导航控制器的任何选项卡都有疑问,如果它们位于“更多”选项卡内(我们的应用程序有很多选项卡)。我的解决方法在这里:splinter.com.au/finding-the-currently-visible-view-in-a-uitab
    • 我在 UITabBarController 上创建了与答案相同的类别,并且我还为 UINavigationController 创建了一个类别并仅返回 YES,但我似乎无法让它工作,对不起.. :/ 你是怎么做到的?
    【解决方案3】:

    是的 - 它比我想象的要容易!

    没错,标签栏是不可见的......但这仍然是一个基于标签栏的应用程序的核心。

    除非 UITabBarController 允许自动旋转,否则所有其他视图都将关闭。因此,只需将 UITabBarController 子类化并适当地响应 shouldAutorotateToInterfaceOrientation:(而不是像 Xcode 那样使其成为 App Delegate 的一部分)。

    你是怎么做到的?很高兴你问。仅当您使用 Xcode 默认值创建了一个标签栏控制器应用程序时,才执行这些步骤。 (在尝试之前备份你的工作!免责声明,yadda yadda。)

    1. 创建一个新的 UIViewController 子类(我们称之为 VC)。将其调整为 UITabBarController 的子类,显式委托为 UITabBarControllerDelegate
    2. 将您的 App Delegate 中的所有 Tab Bar 委托位移植到这个新的 VC 中。
    3. 在新 VC 的 viewDidLoad 方法中,将 self.delegate = self; 添加到末尾。
    4. MainWindow.xib(或定义标签栏控制器和标签栏的任何位置)中,选择您的标签栏控制器对象并转到身份检查器(Cmd-4)。将类更改为您的新 VC,而不是标准的 UITabBarController 类。

    现在我们开始营业了。只需将其添加到新的 VC 源中即可:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        return YES; // Adjust to taste
    }
    

    为什么是委托的东西? IB 文件的所有者是 UIApplication,我无法通过 IB 将代理绑定到我的新 VC。因为我希望有机会响应委托方法,所以我明确地添加了它。如果您不需要它,可以将其排除在外。 (如果这可以在 IB 中完成,请有人插话!)

    剩下的唯一技巧是将其设置为YES有选择地。您可能不想一直支持自动旋转(就像我的情况一样)。这是我的做法。首先,我将新添加的方法(从上面)更改为:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {   
        return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
    }
    

    现在我可以从我的应用程序的任何 VC 中响应相同的方法,它会冒泡到 Tab Bar 控制器!例如,在我的应用中,我有一个 VC,我只想在肖像中显示,所以我这样回应:

    return (interfaceOrientation == UIInterfaceOrientationPortrait);
    

    但是,同样的 VC 可以将用户带到一个照片库,我确实希望允许一些旋转。在那个 VC 的 autorotate 方法中,我的反应不同:

    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    

    现在画廊视图将允许自动旋转到除倒置纵向之外的所有方向,而且当我返回视图控制器链时,方向恢复为纵向。 :)

    【讨论】:

      猜你喜欢
      • 2010-11-06
      • 2010-11-03
      • 1970-01-01
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多