iOS - UISearchController - definesPresentationContext 布局问题

iOS - UISearchController - definesPresentationContext layout issue

我有一个 UIViewController,带有导航栏 HIDDEN,顶部有几个按钮,UITableView 带有 UISearchController 作为 header . 这是问题所在:当我创建 UISearchController 时,我也有这一行:

    self.definesPresentationContext = YES;

现在发生的事情是,当我使用 UISearchController 进行搜索并单击 UITableView 中的一个结果时,它会打开我的关注 UIViewController(这正是它应该这样做——并且下面的 UIViewController 也正确地隐藏了导航栏)但是它在 UIViewController 的顶部显示了一个灰色的导航栏,即使我正在设置导航栏作为隐藏。

现在当我设置:

    self.definesPresentationContext = NO;

导航栏没有出现在下面的视图中,而是 UISearchController's SearchBar 出现在下面的 UIViewController 中,与它在主视图控制器中的位置相同,即使它显然不应该再存在了。

这是它应该看起来的样子(UIViewController 的顶部):

这是当 `self.definesPresentationContext = YES;

时发生的情况

这就是当 `self.definesPresentationContext = NO;

时发生的情况

我怎样才能回到第一种情况? 更新 这是一个重复此问题的示例项目: http://www.filedropper.com/sampleprojectbugreport

它确实看起来像 iOS 中的错误。如果您根本不打算显示导航栏,您可以子类化 UINavigationController 并覆盖 -setNavigationBarHidden:animated: 方法并对 hidden 值进行硬编码:

-(void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated {
    [super setNavigationBarHidden:YES animated:animated];
}

我已经测试了这个解决方法,它阻止了导航栏的显示。

查看更新的示例项目:http://appsandwich.com/Whosebug/navcontrollersubclass.zip

我也遇到了同样的问题。我使用 KVO 解决了它。 我在 viewWillAppear(_:) 中发现,navigationBar 的 isHidden 是正确的。但是在viewDidAppear(_:)中,navigationBar的isHidden变成了false。我不知道发生了什么事。但是我觉得我可以用KVO捕捉和改变它。

首先,在viewWillAppear(_:)中添加观察者

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.navigationBar.addObserver(self, forKeyPath: "hidden", options: [.new], context: nil)
}

然后,在 observerValue()

中更改导航栏的 isHidden
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard let keyPath = keyPath else { return }    
    if keyPath == "hidden" {
        // you should remove the KVO before set
        navigationController?.navigationBar.removeObserver(self, forKeyPath: "hidden")
        navigationController?.navigationBar.isHidden = true
    } else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
    }
}

现在导航栏已按预期隐藏。 希望对你有帮助。