iPad 上的多个呈现视图控制器和旋转

7
最近我在将一些代码从iPhone应用移植到iPad时遇到了一个问题。这可能与此处描述的问题有关,但我发现那个问题的解释和解决方案都不尽如人意。情况是这样的:
1. 视图控制器'A'(根视图控制器)使用“表单表格”模态呈现样式呈现模态视图控制器(称之为'B')。
2. 视图控制器B使用“全屏幕”模态呈现样式呈现视图控制器'C'。
3. iPad在视图控制器C成为最高级别的呈现视图控制器时旋转。
4. C被解散后,B重新显示,但方向不正确。
据我所知,多个呈现的视图控制器链接在一起不应该有问题,事实上,在Presenting View Controllers from Other View Controllers文档中明确支持此行为。我还在iOS 5 Release Notes中读到了以下声明:
“在iOS 5中,旋转回调不适用于以全屏幕呈现的视图控制器。这意味着,如果您的代码在另一个视图控制器上呈现了一个视图控制器,然后用户随后将设备旋转到不同的方向,那么在解散时,底层控制器(即呈现控制器)将不会接收任何旋转回调。但是请注意,当重新显示控制器时,呈现控制器将接收viewWillLayoutSubviews调用,并且可以从该方法查询interfaceOrientation属性并用于正确布局控制器。”
据我所知,这种情况并没有发生——视图控制器B接收到-shouldAutoRotateToInterfaceOrientation的调用,但是在此调用中,interfaceOrientation参数的值是视图控制器B呈现视图控制器C时的界面方向的值,而不是C被解散时的界面方向的值。由于我们在iPad上,所有这些视图控制器都在-shouldAutoRotateToInterfaceOrientation中返回YES。因此,B的视图边界永远不会改变,所以-willLayoutSubviews从未被调用。
我尝试在B解散C之前在回调中保存视图控制器C的方向,然后在下一次调用-shouldAutoRotateToInterfaceOrientation时使用该信息,并仅为C解散时的方向返回YES。这修复了出现问题的UI,但是视图控制器B没有更新其界面方向到此值,因此后续的模态呈现将从设备的错误侧面动画进入/退出。
有人成功地实现了像这样的视图控制器配置吗?这似乎并不是那么不寻常的情况,所以我有点惊讶它没有像我最初预期的那样工作。
先感谢您。
2个回答

0
在我看来,如果你不使用导航控制器,多个链接的模态视图控制器会导致用户体验混乱和烦恼。我认为视图控制器B应该在一个导航控制器中(如果你不想显示导航栏,也可以不显示)。
模态展示实际上应该是用于单个死胡同实体(一个单独的视图控制器或包含多个子视图控制器的导航控制器)。
顺便问一下,你是说这在iPhone上运行良好但在iPad上不行吗?还是你在iPhone版本上没有允许旋转?
我还找到了这个帖子,它说从根视图控制器呈现模态视图控制器可能会有所帮助。

我同意使用导航控制器作为模态视图的根视图会减少混淆。然而,我试图匹配的设计要求视图控制器B采用表单页样式,视图控制器C采用全屏呈现方式。这似乎是实现所需结果的最简单方法,但不幸的是它似乎存在一些非显而易见的问题。我实际上不确定是否在iPhone上存在同样的问题 - 您正确地认为旋转在手机上被禁用。 - jamie

0

我曾经在iPhone上处理多个模态视图控制器。布局没有问题,除非我的代码处理多个方向时出现了问题。当视图控制器位于另一个视图控制器后面时,自动旋转方法实际上永远不会被调用,因此我也会在viewWillAppear:中进行布局调整。

在viewWillAppear:、willRotateToInterfaceOrientation:duration:和didRotateToInterfaceOrientation:中,我会根据需要调整布局到正确的方向,例如:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self switchToInterfaceOrientation:self.interfaceOrientation];
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:interfaceOrientation duration:duration];
    [self switchToInterfaceOrientation:toInterfaceOrientation];
    // be careful, self.view.frame is still according to self.interfaceOrientation
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    // self.view.frame is updated
    // update something else here
}

- (void)switchToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // update your layout here
}

我不确定上面的代码在iPad上的视图控制器上会有什么行为。由于它支持具有不同模态呈现样式的视图控制器,可能会有一些意外情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接