在 iOS 11 中,关闭模态呈现的导航控制器会导致视觉重复

In iOS 11, dismissing a modally presented navigation controller results in visual duplication

我有一个模态呈现 UINavigationController。在该导航控制器上,推送了两个视图控制器。按下“完成”按钮后,整个模态呈现应该从第二个视图控制器中消失。为此,在 presentingViewController:

上调用 dismiss
@IBAction func doneWasPressed(_ sender: UIBarButtonItem) {
    presentingViewController!.dismiss(animated: true)
}

在 iOS 11 中,当导航控制器中的祖先已呈现 UISearchController,并添加到 navigationItem 时,关闭导航控制器会导致视觉伪像视图的副本在动画视图下方 可见。一旦顶视图移出视图,下面的副本就会突然消失。有关问题的屏幕录像,请参见下面的 gif。

this GitHub repository 中提供了一个可重现的小示例。它是在 Xcode 9 (GM) 使用 Swift 4.

创建的

是否有已知的解决方法?


在准备 minimal, complete, and verifiable example 时,您注意到问题出在 UISearchController 上。我注意到即使在我推送到第二个页面视图控制器(通过带有 UISearchController 的视图控制器)之后,搜索控制器仍然存在:

如果在视图消失时将 isActive 设置为 false,此问题就会消失。

override func viewDidLoad() {
    super.viewDidLoad()

    let searchController = UISearchController(searchResultsController: nil)
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.hidesNavigationBarDuringPresentation = false
    navigationItem.searchController = searchController
    navigationItem.hidesSearchBarWhenScrolling = false
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    navigationItem.searchController?.isActive = false
}

并且,完成此操作后,解雇会按预期进行。


我最初的回答是建议您关闭导航控制器,而不是呈现视图控制器。


如果您以模态方式呈现导航控制器,然后从那里推送几个视图控制器,您不想关闭 presentingViewController,而是要关闭 navigationController,例如:

navigationController?.dismiss(animated: true)

或者,或者,在您想要 return:

的视图控制器上创建一个展开操作
@IBAction func unwindHome(_ segue: UIStoryboardSegue) {
    // this is intentionally blank
}

然后您就可以在 IB 中创建展开转场:

或者,如果您必须以编程方式执行此操作,请在视图控制器和 "exit" 出口之间创建展开转场,然后您可以 performSegue(withIdentifier:sender:).