UITabBarController,MoreNavigationController和设备轮换的圣杯

Joe*_*rea 6 rotation uitabbarcontroller orientation uiviewcontroller iphone-sdk-3.0

更新:首先查看我对这个问题的回答.这似乎是一个错误.已经创建了一个最小的测试用例,并且已经向Apple提交了一份报告.(自iPhone OS 3.1起固定.)

这是一个来自"我如此接近!"的益智游戏.部门.

我有一个基于Tab Bar的iPhone应用程序.每个选项卡都有一个UINavigationController和常见的嫌疑人(导航栏,表格视图......这反过来可以导致另一个VC等).

现在,其中一个较低级别的VC将用于肖像横向模式.但是有一个问题.我们的风景友好的VC应该是AutorotateToInterfaceOrientation:不会被称为开箱即用的!该怎么办?

这就是我们的工作.在我的标签栏控制器中,我已在其自己的文件中实现,我有:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
     return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
Run Code Online (Sandbox Code Playgroud)

这最终将请求传播到我的环境友好型VC,它也响应此消息.我所有的其他VC都没有实现这种方法,所以它们只是采用默认的纵向方向.

问题解决了!!!好极了!

嗯,不太好.:(

当从标签栏控制器的MoreNavigationController的深度调用我的风景友好的VC时,似乎事情并不顺利.

我决定在前四个标签栏UINavigationControllers中调用的VC与在MoreNavigationController中调用的同一个VC之间进行比较/对比.这将是一个非常详细的,所以请耐心等待.希望通过游戏发挥作用证明有用的东西.

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

对.首先,让我们选择前四个标签栏项目之一并深入查看我们的VC.

我们将选择第三个导航栏项,这是第三个导航控制器.我们深入研究支持旋转的VC.快速检查确认父母确实是我们标签栏的视图控制器列表中的第三个导航控制器.好!

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

因此,标签栏控制器会将shouldAutorotate消息转发给第三个导航控制器......但我们的旋转友好型VC最终会获得消息.(我在这里没有做任何特别的事情.也许所需的VC获取消息,因为它是顶级和/或可见的VC?)无论如何,我们旋转到横向,事情调整大小,一切都很好."巨大的成功!"

现在让我们点击后退按钮并弹出VC堆栈,在此过程中保持横向模式.再次查询标签栏控制器.

在这里稍微休息的时间.我们的nav控制器的topViewController仍然是旋转友好的VC,但是visibleViewController现在设置为UISnapshotModalViewController!嘿.从来没有见过这个...但埃里卡萨顿有.看起来像是"消失的视图控制器"(在这种情况下肯定是真的 - 它正好消失了).

随着我不断介入,可见VC保持为快照,但顶级VC最终会更改为堆栈上的下一个VC,因为我的特殊VC最终会消失.很公平.

所以就是一切运作良好的场景.

现在让我们尝试相同的测试,只是这次我们将转到MoreNavigationController(更多标签栏项目)并深入查看与以前相同的VC类.在我的情况下,它恰好是标签栏控制器的VC列表中的第7个.

我们进入旋转感知VC和...这次它被要求直接旋转!Tab Bar Controller根本不会被要求获得轮换许可.嗯.

快速检查父VC显示它是一个MoreNavigationController.好的,这是有道理的.

现在让我们尝试旋转设备.没有接到的话.我们的断点都没有被击中.不在我们的VC中.不在我们的标签栏控制器中.(咦?!?!)

O型kaaaay.让我们弹出堆栈,回到同一个VC并尝试再次旋转.奇怪的.现在我们在Tab Bar Controller中接到一个要求自动旋转许可的电话.在这里,所选的Controller是我们值得信赖的Nav控制器(#7),但这次它的visibleViewControllertopViewControllerSET TO NIL!

一旦我们从这里继续,调试器控制台中会出现一条神秘的消息:

使用两阶段旋转动画.要使用更平滑的单阶段动画,此应用程序必须删除两阶段方法实现.

神秘,因为我没有使用两阶段旋转动画!在我的源代码中的任何地方都没有使用SecondHalf方法变体.

唉,我的旋转感知VC永远不会被告知旋转正在发生(即使旋转确实发生在屏幕上),所以当然我的观点都被结果弄脏了.随之而来的是混乱和悲伤.:(

在这一点上我们甚至不会打扰弹出堆栈.

我认为View Controller doc暗示了可能出现的问题:

如果要在方向更改期间执行自定义动画,可以通过以下两种方式之一执行此操作.方向更改过去分两步进行,通知发生在旋转的开始,中间和结束点.但是,在iPhone OS 3.0中,添加了对一步执行方向更改的支持.使用一步式方向更改往往比旧的两步式更快,并且通常建议用于任何新代码.

我想知道MoreNavigationController是否仍在响应两步过程,因此绊倒任何使用一步过程的尝试?请注意,如果您回复两步消息,则单步变体将不起作用(同样,根据文档).我没有对他们做出回应,但我对幕后的IS有一种潜在的怀疑.

事实上,如果我注释掉单步方法,并尝试响应willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration : ,我收到备忘录!但它仍然没有非常干净地从堆栈中弹出(就视觉效果而言).更奇怪的是:willAnimateFirstHalfOfRotationFromInterfaceOrientation:持续时间:不叫,甚至当我试图潜入到自我的呼叫(使用FirstHalf消息)shouldAutorotateToInterfaceOrientation: .它在跟踪期间立即返回,就好像我从未定义它一样.叹.

所以这就是一场比赛.

总之,有没有成功处理过Tab Bar Controller的MoreNavigationController中调用的VC的一步设备轮换?询问心灵想知道!

Vic*_*orB 7

Apple建议不要对UITabBarController进行子类化,因此我找到了一种使用类别来处理自动旋转的简单方法.它不会修复你的更多...视图控制器的错误,但我认为这是一种更加苹果友好的方式来完成工作(并意味着更少的子类化).

为了使我的应用程序中的每个选项卡都能正确自动旋转,我已经在我的自定义视图控制器中定义了-shouldAutorotateToInterfaceOrientation:但它们都在UITabBarController中的UINavigationControllers中,因此消息不会从链中发送到我的VC,直到这两个也回应.所以我将以下行添加到我的app委托文件中:

添加到MyAppDelegate.h的底部

@interface UITabBarController (MyApp)
@end

@interface UINavigationController (MyApp)
@end
Run Code Online (Sandbox Code Playgroud)

添加到MyAppDelegate.m的底部

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

@implementation UINavigationController (MyApp) 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return YES;
}
@end
Run Code Online (Sandbox Code Playgroud)