更新:见我回答这个问题第一。这似乎是一个错误。一个最小的测试用例已经创建并报告已经提交苹果公司。 (固定为iPhone OS 3.1。)

下面是从一个益智游戏“我是如此接近!”部。

我有一个基于酒吧-Tab键iPhone应用程序。每个选项卡设有的的UINavigationController 用通常的嫌疑人(导航栏,表视图...这反过来又可以导致另一个VC,等)。

现在,那些较低级的VC中的一个是在波泰特横向模式中使用。但是有一个问题。我们景观友好VC的 shouldAutorotateToInterfaceOrientation:的将不会被调用外的开箱!怎么办?

下面就是我们要做的。在我的标签栏控制器,这是我在自己的文件已经实现了,我有这样的:

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

这结束了传播所述请求到我的景观友好VC,它也响应于该消息。我的所有其他风险投资不实行此方法,因此他们只需使用默认纵向走了。

问题解决!!!耶!

那么,的不太:(

好像事情并不那么好走的时候我景观友好VC从深处中调用标签栏控制器的 MoreNavigationController

我决定比较从前四个标签栏之一内调用的VC之间/对比度的 UINavigationControllers ...和内<强从名为同一VC > MoreNavigationController 即可。这将是一个有点超详细,所以大家多多包涵。希望通过播放的播放为侦探的事情了证明是有用的。

当应用程序加载,有几个初始调用标签栏控制器的shouldAutorotate ...方法。在这些早期的情况下,的 selectedViewController 是零。然而,我们最终完成加载,初始标签项目被选择,并且一切都很好。

右。首先,让我们挑的前四个标签栏项目中的一个,并深入到我们的VC。

我们来接第三的导航栏项目,所以这是第三个导航控制器。我们深入到我们的VC支持旋转。快速检查确认父的确是从我们标签栏的视图控制器列表中的第三个导航控制器。好!

让的旋转设备。标签栏控制器被要求自转(参见上面的代码)。我们观察到的 selectedViewController 也是第三个导航控制器,再加上导航控制器的顶部可见视图控制器都设置为我们支持旋转信赖的VC。

因此,标签栏控制器将转发的 shouldAutorotate 的消息到第三导航控制器...但我们旋转友好VC最终获取消息。 (我没有做什么特别的东西在这里。也许所需的VC获取消息因为它的顶部和/或可见VC?)在任何情况下,我们旋转为横向,事情大小,一切都很好。 “取得圆满成功!”

现在,让我们打的后退按钮,并在弹出堆栈VC,留下横向模式的过程中。标签栏控制器被再次查询。

时间有点一边在这里。在 topViewController 作为我们的导航控制器仍然是旋转友好VC,但 visibleViewController 现在设置为 UISnapshotModalViewController !嘿。从来没见过这个人之前...但埃里卡丧盾已经的。看起来像它为“消失视图控制器”(在这种情况下是千真万确 - 它消失正常的)

由于我一直踩着通过,可见VC保持为快照,但顶级VC最终切换到下VC在堆栈上,因为我的特殊VC最终消失。够公平。

所以的这就是的场景WHERE一切正常。

现在,让我们尝试相同的测试,只是这一次,我们要去的 MoreNavigationController (更多标签栏项目),并像以前一样深入到同一个VC类。在我的情况正好是7人在标签栏控制器的VC名单。

我们进入旋转感知VC和... ...这一次被要求以旋转的直接的!标签栏控制器是的的请求允许在所有的旋转。 HMM。

父的快速检查VC表示它是一个的 MoreNavigationController 即可。行,这是很有意义的。

现在让我们尝试旋转设备。的 NOTHING被调用即可。我们的断点没有被击中。不是在我们的VC。不是在我们的标签栏控制器。 (咦?!?!)

O形kaaaay。让我们弹出堆栈,重新回到同一VC,尝试再次旋转。奇怪的。现在,我们在标签栏控制装置的呼叫请求自转许可。在这里,所选择的控制器是我们值得信赖的导航控制器(#7),但这次它的 visibleViewController topViewController 设置为nil 的!

在我们从这里继续,出现在调试器控制台神秘消息:

  

使用两级旋转动画。至   使用更平滑的单级   动画,此应用程序必须   除去两阶段方法   的实施方式。

由于神秘的我不使用两阶段旋转动画!否 SecondHalf 方式变体中发挥任何地方在我的源代码。

唉,我的旋转感知VC从未告知旋转发生(即使旋转也出现在屏幕上),所以当然我的看法是都搞砸了结果。混乱和悲伤随之而来。 :(

我们甚至不会打扰此时弹出堆栈。

我认为在可能出现的问题的视图控制器文档提示:

  

如果您要执行定制   定向期间动画   变化,你可以在两个一个这样做   方法。使用方向变化   发生在两个步骤中,使用通知   在开始出现,中,   旋转和终点。   然而,在iPhone OS 3.0,支持是   增加了执行方向   变化在一个步骤中。采用一步法   取向的变化往往是快   比旧过程分为两个步骤,是   一般建议任何新   代码。

不知的 MoreNavigationController 仍响应该两个步骤的过程,并且因此绊倒任何企图使用一步法?需要注意的是,如果你到两步的消息作出反应,一步法变种将无法正常工作(再次,每文档)。我不会回应他们,但我有一个鬼鬼祟祟的怀疑的东西背后的场面。

事实上,如果我注释掉单步方法,并尝试为 willAnimateSecondHalfOfRotationFromInterfaceOrientation回应:持续时间:后,我的的得到备忘录!但它仍然没有弹出堆栈很干净(在视觉效果方面)。更奇怪:的 willAnimateFirstHalfOfRotationFromInterfaceOrientation:持续时间:不叫,甚至当我试图偷看中的 shouldAutorotateToInterfaceOrientation自我呼叫(使用FirstHalf消息):即可。一个跟踪期间它会立即返回,就好像我从来没有定义它。叹息。

所以这是播放的播放。

总之,已成功地处理一步法设备旋转为VC从标签栏控制器的MoreNavigationController内引用?好奇之心想知道!

有帮助吗?

解决方案

苹果建议不要子类的UITabBarController,所以我发现一种简单的方法来处理用自转类别来代替。它不与更多...视图控制器解决您的错误,但我认为这是完成工作(并意味着更少的子类你)的苹果更友好的方式。

要尽一切选项卡在我的应用程序自动旋转正常,我定义-shouldAutorotateToInterfaceOrientation:在我的自定义视图控制器,但他们是一个的UITabBarController内的所有内部UINavigationControllers,因此消息不会得到链向下发送到我的VC直到那两个也作出回应。所以我添加以下行到我的应用程序的委托文件:

  

加进MyAppDelegate.h的底部

@interface UITabBarController (MyApp)
@end

@interface UINavigationController (MyApp)
@end
  

加进MyAppDelegate.m的底部

@implementation UITabBarController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}
@end

@implementation UINavigationController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}
@end

其他提示

看来,我们有一个错误。我创建了一个可重复的,最小的测试案例,并通过苹果的软件缺陷报告报告说,它(雷达问题7139857

<强>更新:这已被固定为iPhone OS 3.1的

的基本问题是:

  

查看控制器已经在   导航控制器堆栈不   接收   的 willAnimateRotationToInterfaceOrientation:持续时间:   消息时,一个标签栏控制器的   “更多导航控制器”是在   使用

此问题确实当标签栏项目视图控制器是基本视图控制器发生。只有当他们导航控制器和当“更多”导航层次结构是在使用中。

在控制台消息(关于两级旋转动画)表明框架(更多导航控制器?)依然采用了两阶段的动画,即使单级现在推荐如iPhone OS 3.0的<内的东西/ p>

这可以解释为什么的 willAnimateRotationToInterfaceOrientation:未在该特定情况下被调用。每苹果的视图CONTROLER文档,该消息将不会被当两阶段,第一/第二半取向消息被响应调用来代替。

一个稍作修改的版本 Victorb的回答其允许每一个视图控制器,以决定是否允许旋转的

这里作为用于更容易的复印&分叉要旨

AppDelegate.h

@interface UITabBarController (MyApp)
@end

@interface UINavigationController (MyApp)
@end

AppDelegate.m

@implementation UITabBarController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    UIViewController *selectedVC = [self selectedViewController];
    if ([selectedVC respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
        return [selectedVC shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
    }

    //optimistic return - if you want no rotation, you have to specifically tell me!
    return YES;
}
@end

@implementation UINavigationController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    UIViewController *visibleVC = [self visibleViewController];
    if ([visibleVC respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
        return [visibleVC shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
    }

    //optimistic return - if you want no rotation, you have to specifically tell me!
    return YES;
}
@end
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top