关闭与 uisplitviewcontroller 结合使用的模式视图后出现问题

Posted

技术标签:

【中文标题】关闭与 uisplitviewcontroller 结合使用的模式视图后出现问题【英文标题】:Problem after dismissing a modal view used in conjunction with a uisplitviewcontroller 【发布时间】:2010-05-08 21:18:14 【问题描述】:

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

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

我添加了一个名为 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) 开始横向,结束横向:一切正常。 willHideViewController 和 willShowViewController 方法未在 RootViewController 中调用(如预期的那样)

2) 开始横向,结束纵向:UI 看起来不错。 willHideViewController 运行两次(为什么?)

3) 开始纵向,结束纵向:UI 看起来不错。 willHideViewController 运行一次(如预期)

4) 开始纵向,结束横向:“根列表”按钮保留在详细视图中(拆分视图的右侧。willHideViewController 和 willShowViewController 均未调用(为什么??)

关于为什么 #2 和 #4 的行为不符合预期的任何想法?

【问题讨论】:

【参考方案1】:

我遇到了完全相同的问题(上面的#4)。我使用viewDidAppear:animated 解决了它,然后检查视图的高度以查看它是横向还是纵向。 (呸,堵嘴等)我对那个“解决方案”一点也不满意。

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

【讨论】:

【参考方案2】:

很遗憾,这不是错误。这似乎是一种预期行为。

我在 ios 5.0 的 iOS 发行说明中的​​“注意事项和已知问题”部分找到了这一点:

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

我遇到了同样的问题。

在回答 (2) 时,它似乎是一个错误。我注意到,当模态视图被推送到拆分视图上时,方向消息在某处排队并且在模式视图被关闭并且拆分视图可见之前不会被处理,但我仍然希望只得到一个回调。

对于 (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,“detail”是用于详细视图控制器(右侧大小)的 IBOutlet。

请注意,在我的例子中,详细视图是一个 UINavigationController。您可能需要不同的代码才能从视图控制器中获取 barButtonItem。

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于关闭与 uisplitviewcontroller 结合使用的模式视图后出现问题的主要内容,如果未能解决你的问题,请参考以下文章

在 UIViewControllers 和 UISplitViewController 之间导航 [关闭]

关闭uisplitviewcontroller中的NavigationController后如何重新加载tableView?

在 iPhone 6 Plus 上关闭 UISplitViewController 弹出框时 UIWebView 被拉伸

UISplitViewController 重新加载数据

UINavigationController 与 UISplitViewController

iPad:UISplitViewController 与 iAds AdBanner 在详细视图中 - 大小