使用 UISearchController 时,iOS 13 UIBarButtonItem 不可点击和重叠 UINavigationBars
Posted
技术标签:
【中文标题】使用 UISearchController 时,iOS 13 UIBarButtonItem 不可点击和重叠 UINavigationBars【英文标题】:iOS 13 UIBarButtonItem not clickable and overlapping UINavigationBars when using UISearchController 【发布时间】:2019-09-27 12:32:06 【问题描述】:我有一个导航栏,其中包含一些 UIBarButtonItem
按钮和一个 UISearchBar
像这样连接
var searchController: UISearchController!
override func viewDidLoad()
super.viewDidLoad()
title = "Test"
tableView.delegate = self
tableView.dataSource = self
searchController = UISearchController(searchResultsController: nil)
navigationItem.searchController = searchController
// This leads to the bug
searchController.hidesNavigationBarDuringPresentation = false
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(leftTapped))
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(rightTapped))
场景:我点击搜索栏,然后点击取消。
问题 1:条形按钮对触摸没有反应,除非我触摸屏幕的最外层像素(仅通过模拟器和鼠标点击才有可能)。
问题 2:当我推动另一个视图控制器时,导航项重叠。
当我使用 hidesNavigationBarDuringPresentation = true
时,它会像预期的那样工作。
该问题出现在使用 Xcode 11.0 和 11.1 的缺口和非缺口 iPhone ios 13.0 和 13.1 上。
这是整个测试项目: https://github.com/fl034/HidesNavigationBarDuringPresentationTest
我已经提交了一份雷达文件(你也应该提交),但也许你们中的一些人已经有了解决方法?
更新 1:iOS 13.1.1 中仍然存在错误
更新 2:在 iOS 13.2 测试版中修复了错误(感谢 @Ben Gomm)
【问题讨论】:
我也注意到了这一点 - 必须将hidesNavigationBarDuringPresentation
设为 true 以避免此错误,但这不是我想要的外观。我认为这是一个错误。启用大标题后,取消搜索栏似乎会出现第二个大标题,该标题不会随滚动视图的其余部分一起滚动。
非常不错的演示,但您应该消除所有对演示错误而言不必要的内容。您不需要标签栏控制器。您不需要栏按钮项目!只需点击表格行进行导航就足以表明导航栏已损坏。
同意。除了我需要条形按钮来证明条形按钮不再可点击。
在 iOS 13.1.2 上仍然损坏
我遇到了同样的问题,但我不能将 hidesNavigationBarDuringPresentation 设置为 true,因为当 UISearchBar 是第一响应者时,我仍然需要显示条形按钮
【参考方案1】:
视图调试器揭示了这个错误发生了什么。正在复制导航栏的内容。以下是显示搜索之前导航栏的外观:
这是之后的样子:
两个副本视图和额外的 UILabel 是问题所在。我不知道他们在那里做什么,也找不到删除它们的方法。
编辑顺便说一句,我认为 Apple 的一些应用程序显示了相同的错误。更容易查看您是否有大标题,因为这样您就可以同时看到大标题和额外标签:
【讨论】:
【参考方案2】:我现在正在使用此解决方法,因为我希望我的大多数用户在搜索处于活动状态时都能看到导航栏(出于几个特定于 app-ux 的原因)。
var isIosVersionWithNavigationBarBug: Bool
if #available(iOS 13.2, *)
return false
if #available(iOS 13.0, *)
return true
return false
在我的搜索控制器中,我这样使用它
mySearchController.hidesNavigationBarDuringPresentation = isIosVersionWithNavigationBarBug
因此,如果 iOS 13.2 正在发布并且用户对其进行了更新,那么解决方法将不再适用。
【讨论】:
@n8gray 这不是真的,#available 绝对是运行时检查。资料来源:我们在超过 2000 万用户下载且从未出现过问题的应用中使用此功能。它甚至在您提供的链接中说:“如果您只想检查用户是否至少运行特定版本”,请使用#available @simonthumper:没错。不知道我在想什么。遗憾的是 Swift 选择使用#
字符来标记在编译时评估的两个值(如#if
)和运行时检查如#available
。在这方面 C 更好。
这绝对是一个奇怪的!做出了一些奇怪的决定,但总的来说我是粉丝!只是想确保发现此内容的其他人不会感到困惑:)【参考方案3】:
这似乎在 iOS 13.2 beta 中得到修复,我使用 Xcode 11.2 beta (11B41) 测试了上面的示例项目。
【讨论】:
【参考方案4】:并不为此感到自豪,但我现在通过这个 hack 让它工作了。
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated)
let viewsToRemove = self.navigationController?.navigationBar.subviews.flatMap( (view) in
view.subviews.filter type(of: $0) == UILabel.self
)
viewsToRemove?.forEach $0.removeFromSuperview()
【讨论】:
这仅修复了双倍的标题标签。激活一次搜索后,Sill 无法单击我的栏按钮项。以上是关于使用 UISearchController 时,iOS 13 UIBarButtonItem 不可点击和重叠 UINavigationBars的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 13 中使用 UISearchController 时,状态栏在 iOS 中变为白色
将 UISegmentedControl 与 UISearchController 一起使用
将 unwind segue 与 UISearchController 一起使用时出错
按下取消按钮时如何防止 UISearchController 关闭?