嵌入 UISplitViewController 时,UINavigationBar 中缺少 iOS11 UISearchBar

Posted

技术标签:

【中文标题】嵌入 UISplitViewController 时,UINavigationBar 中缺少 iOS11 UISearchBar【英文标题】:iOS11 UISearchBar missing in UINavigationBar when embedded in UISplitViewController 【发布时间】:2017-09-24 06:12:41 【问题描述】:

UISplitViewController 的详细视图上使用新的 ios 11 navigationItem.searchController 方法时似乎会发生奇怪的事情。

searchBar 在第一个演示文稿中部分显示为空白,然后出现在错误的UITableViewController 中,但在UITableViewController 的几次推送和弹出后自行更正。

我以前把searchBar放在tableHeaderView里面,但是我按照WWDC的推荐改了代码:

if (@available(iOS 11.0, *)) 
    self.navigationItem.searchController = self.searchController;
    self.navigationItem.hidesSearchBarWhenScrolling = NO;
 else 
    self.tableView.tableHeaderView = self.searchController.searchBar;

此示例使用标准示例代码(UISplitViewController 的默认项目和针对 iOS 11 更新的 UISearchController 的 Apple 演示(使用单个 UITableViewController))。

包含searchController 的初始视图如下所示:

然后单击 UITableView 项目会产生以下结果:

但是,在单击 UITableView 项目并返回两次后 - 它看起来应该:

和:

我试图确定为什么 UISearchController 的 Apple 示例有效而我的代码无效。主要区别在于它嵌入在详细视图中的UISplitViewController 中。这意味着如果以紧凑模式显示,堆栈中会有一个额外的UINavigationController。我发现如果我的序列避免了额外的UINavigationController - 它可以正常工作(但会中断设备旋转)。同样将 segue 更改为 modal 允许它工作。

我注意到这类似于这个老问题:UISplitViewController with new UISearchController issue with UISearchBar

我创建了一个演示问题的示例项目 (sample code: searchControllerDemo)

我不知道发生了什么。因此,我们将不胜感激任何帮助。

【问题讨论】:

在通过prefersLargeTitles 显示大标题时,我也遇到了细节视图控制器的问题。在 iPhone 上:在详细视图控制器中出现一个空白区域,而不是大标题。向上滚动表格视图时,标题通常以 iOS 10 中的常规尺寸显示...在 iPad 上:一切都像魅力一样。我使用了 Master-Detail 应用程序模板,一切似乎都在两个设备上完美运行,大型标题搜索控制器 是的 - 问题似乎只出现在紧凑型 (iPhone) 尺寸类中。 iPad 工作正常。我尝试 navigationItem.searchController 的唯一原因是因为它旨在解决 iPhone X 横向问题。我正在考虑在我的应用程序中禁用 iPhone 横向模式作为解决方案。生命太短暂了。 好的,我用大标题解决了这个问题,也许这会以某种方式帮助你解决UISearchBar...我实际上也想自己在细节视图控制器中嵌入一个,但会调查稍后... UISplitViewController 有很多复杂性。我已经包含了对一个函数的调用,该函数将视图(包括大标题)设置为详细视图控制器中的计算属性。因此,在主视图控制器中设置此属性后,视图已正确设置为大标题。在viewDidLoad 中仍然会再次调用视图设置功能 嗨迈克尔 - 你有解决这个问题的办法吗?我现在正在与同样的事情作斗争,但没有运气! 当详细视图控制器首次出现时,您是否在控制台中打印了这个? +[CATransaction synchronize] called within transaction 【参考方案1】:

自从这件事爆发以来已经有一段时间了,但我想在这里留个便条给遇到同样问题的人......

在紧凑宽度的设备上,在从主视图控制器切换到细节时,细节导航控制器位于主视图控制器之上,这与两个导航控制器具有各自独立的根视图控制器的常规宽度不同。

因此,详细视图控制器的UINavigationController 需要在使用UISplitViewControllerDelegate 方法在组合宽度设备中进行segue 时删除:splitViewController(_:showDetail:sender:)

func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool 
    if splitViewController.isCollapsed, let navController = vc as? UINavigationController 
        if let detailVC = navController.topViewController 
            splitViewController.showDetailViewController(detailVC, sender: sender)
            return true
        
    
    return false

【讨论】:

使用 Xcode 10 的 iOS 12 上仍然会出现问题,您的解决方案可以节省我的工作。

以上是关于嵌入 UISplitViewController 时,UINavigationBar 中缺少 iOS11 UISearchBar的主要内容,如果未能解决你的问题,请参考以下文章

UISplitViewController 一致分隔符

UISplitViewController - 并排或纵向叠加

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

将 UIToolBar 放在 UISplitViewController 上方?

UISplitViewController + UISearchController 显示搜索细节

iPad 上的 UITraitCollection 和 UISplitViewController