在解除与uisplitviewcontroller结合使用的模态视图后出现问题

时间:2010-05-08 21:18:14

标签: ipad uiviewcontroller uisplitviewcontroller modalpopups

我很难理解为什么会发生以下情况(以及如何解决)。

我使用基于拆分视图的应用程序创建了一个应用程序。

我添加了一个名为showTheModal的UiBarButtonItem,它调用RootViewController.m中的这个方法:

- (IBAction)showTheModal:(id)sender {
theModalController.modalPresentationStyle = UIModalPresentationFullScreen;
theModalController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:theModalController animated:YES];

if ([detailViewController popoverController] != nil)
    [[detailViewController popoverController] dismissPopoverAnimated:YES];

当然,BarButtonItem显示在默认根控制器的底部(横向拆分视图的左侧)或弹出窗口的底部(如果是横向)。

模态视图被放置在工具栏中的按钮解除。它调用以下内容:

[self dismissModalViewControllerAnimated: YES];

我遇到的问题是如果旋转屏幕,则模态已启动。以下是在不同场景中发生的事情(start是指showTheModal按钮被击中时的方向,end是指当我点击dismissModal按钮时的方向)。

1)开始景观,结束景观:一切都很好。在RootViewController中没有调用willHideViewController和willShowViewController方法(如预期的那样)

2)开始横向,结束肖像:UI显示正常。 willHideViewController运行TWICE(为什么?)

3)开始肖像,结束肖像:UI显示正常。 willHideViewController运行一次(如预期的那样)

4)启动纵向,结束横向:“根列表”按钮保留在详细视图中(拆分视图的右侧.HideViewController和willShowViewController都不会被调用(为什么?)

为什么#2和#4的行为不符合预期的方式?

5 个答案:

答案 0 :(得分:1)

我遇到了完全相同的问题(上面#4)。我使用viewDidAppear:animated解决了这个问题,然后检查了视图的高度,看它是否在横向与纵向之间。 (Yuck,gag等)我对这个“解决方案”一点也不满意。

可能相关:我注意到纵向模式下的按钮在旋转到横向后很慢消失,即按钮在旋转完成后出现一秒钟。但是,在Mail.app中,一旦旋转开始,“收件箱”按钮就会消失。 Apple的做事与他们在文档中推荐的不同吗?也许有一种更有效的方式来显示/隐藏主视图按钮?

答案 1 :(得分:1)

不幸的是,这不是一个错误。这似乎是一种预期的行为。

我在“iOS 5.0发行说明”中的“Notes和已知问题”部分中找到了这个:

  

iOS 5中的旋转回调不适用于视图控制器   全屏显示。这意味着如果您的代码   在另一个视图控制器上显示一个视图控制器,然后是   用户随后将设备旋转到不同的方向   解雇,基础控制人(即提出控制人)将   没有收到任何轮换回调。但请注意提示   控制器将在接收到viewWillLayoutSubviews时调用   重新显示,并可以从中查询interfaceOrientation属性   这个方法用于正确布局控制器。

答案 2 :(得分:0)

对于诊断,您是否尝试首先解除弹出视图?或者通过打印(id) sender来记录谁正在调用该方法?

答案 3 :(得分:0)

我认为这是一个需要向Apple Development报告的错误。

我通过使用UIModalPresentationPageSheet格式呈现我的模态视图来解决部分问题。

答案 4 :(得分:0)

我遇到了同样的问题。

在回答(2)时,它似乎是一个错误。我注意到当一个模态视图被推到一个splitview上时,方向消息在某个地方排队,直到模态视图被解除并且splitview可见但我仍然希望只能得到一个回调时才会被处理。

对于(4),这似乎也是一个错误。幸运的是,didRotate ...事件仍然通过,所以我的解决方案是子类UISplitViewController并在这种情况下显式调用委托的willShowViewController方法:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    //Work around a bug where UISplitViewController does not send 
    //willShowViewController after a modal is presented in portrait
    //but dismissed in landscape.
    UIInterfaceOrientation orientation = self.interfaceOrientation;
    if ( (orientation == UIInterfaceOrientationLandscapeLeft )
        || (orientation == UIInterfaceOrientationLandscapeRight) )
    {
        UINavigationItem* item = [detail.navigationBar.items objectAtIndex:0];
        UIBarButtonItem* barButtonItem = [item leftBarButtonItem];
        [super.delegate splitViewController:self willShowViewController:master invalidatingBarButtonItem:barButtonItem];
    }
}

这里,“master”是一个IBOutlet,它引用了splitview的主视图控制器(左侧),“detail”是一个IBOutlet,用于详细视图控制器(右手大小)。

请注意,在我的情况下,详细视图是UINavigationController。您可能需要不同的代码才能从视图控制器获取barButtonItem。

此外,这有一个副作用,即调用willShowViewController两次进行正常旋转,但在我的情况下这不是问题。