definePresentationContext 应设置为 YES,但在与 UISearchController 结合使用时会中断导航

Posted

技术标签:

【中文标题】definePresentationContext 应设置为 YES,但在与 UISearchController 结合使用时会中断导航【英文标题】:definesPresentationContext should be set to YES, but breaks navigation when used in combination with a UISearchController 【发布时间】:2019-10-10 08:34:58 【问题描述】:

对于在常规UIViewController 中使用UISearchController 的设置(也有包含一些项目的表格视图),我收到以下警告The topViewController of the navigation controller containing the presented search controller must have definesPresentationContext set to YES

但是,在 ViewController 上设置 definesPresentationContext = true 会破坏我在 Search 处于活动状态时在 NavigationController 上推送新 ViewController 的能力,这首先会破坏搜索的目的(我想搜索,然后如果用户点击结果,将其推送到导航堆栈上)。

在尝试推送新的 ViewController 之前,我已经设置了 searchController.isActive = false

在推送另一个视图之前,我还需要做什么才能关闭UISearchController

// The ViewController is presented inside a UINavigationController
class ViewController: UIViewController, UITableViewDelegate 

    override func viewDidLoad() 
        super.viewDidLoad()

        let searchController = UISearchController(searchResultsController: nil)
        navigationItem.searchController = searchController

        // If not set to true, triggers the following error:
        //    "The topViewController of the navigation controller containing
        //     the presented search controller must have definesPresentationContext set to YES"
        definesPresentationContext = true
    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        navigationItem.searchController.isActive = false

        // If definesPresentationContext is true, triggers the following 
        // error when the search bar is/was focused at the time of selection:
        //     "pushViewController:animated: called on UINavigationController while an existing transition
        //      or presentation is occurring; the navigation stack will not be updated."
        navigationController?.pushViewController(UIViewController(), animated: true)
    

【问题讨论】:

【参考方案1】:

事实证明navigationItem.searchController.isActive = false 将关闭搜索栏,但以动画方式。因此,此时转换仍在进行中,导致“第二次”导航失败。

UIView.performWithoutAnimation 中调用块也不起作用。

所以解决方案是使用UISearchController.dismiss(animated:completion) 将其关闭,即

searchController.dismiss(animated: false) 
    navigationController?.pushViewController(UIViewController(), animated: true)

【讨论】:

以上是关于definePresentationContext 应设置为 YES,但在与 UISearchController 结合使用时会中断导航的主要内容,如果未能解决你的问题,请参考以下文章

UISearchController 出现在 NavigationBar 后面