iOS 11 UINavigationBar UISearchBar 和 UIBarButtonItem 重叠
iOS 11 UINavigationBar UISearchBar and UIBarButtonItem overlap
在iOS11中,如果你设置一个UISearchBar为navigationItem的titleView。然后添加/删除 UIBarButtonItem 到 navigationItem.leftBarButtonItems。 UIBarButtonItem 将与 UISearchBar 重叠。
重现步骤:
- 新建单一视图Xcode 项目
- 在故事板的 UINavigationController 中嵌入 ViewController
像这样修改ViewController.swift
class ViewController: UIViewController {
let button = UIBarButtonItem(barButtonSystemItem: .add, target: nil, action: nil)
override func viewDidLoad() {
super.viewDidLoad()
let searchBar = UISearchBar()
searchBar.searchBarStyle = .minimal
navigationItem.titleView = searchBar
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.horizontalSizeClass == .regular {
navigationItem.leftBarButtonItem = button
} else {
navigationItem.leftBarButtonItem = nil
}
}
}
环境:Xcode9.2,iOS11.2.2
我的问题是:有没有办法让 UINavigationBar 正确布局项目,或者我在这里做错了什么?谢谢!
尝试DispatchQueue.main.async
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
DispatchQueue.main.async {
if self.traitCollection.horizontalSizeClass == .regular {
self.navigationItem.leftBarButtonItem = self.button
} else {
self.navigationItem.leftBarButtonItem = nil
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: false)
navigationController?.setNavigationBarHidden(false, animated: true)
}
重置 viewWillAppear
中的 navigationItem.titleView
。
设置 titleView = nil
并返回搜索栏以强制强制导航栏重新布局。
类似于:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.titleView = nil
navigationItem.titleView = self.searchBar
}
更多详情
我喜欢使用 traitCollectionDidChange
的公认解决方案。
但是,该解决方案不适用于(并且仅适用于!)iPhone 11 Pro Max(目前iOS 14.4)。
这是一个非常奇怪的问题,但 viewWillAppear
中的重置是我发现适用于所有设备的唯一可靠解决方案。
在iOS11中,如果你设置一个UISearchBar为navigationItem的titleView。然后添加/删除 UIBarButtonItem 到 navigationItem.leftBarButtonItems。 UIBarButtonItem 将与 UISearchBar 重叠。
- 新建单一视图Xcode 项目
- 在故事板的 UINavigationController 中嵌入 ViewController
像这样修改ViewController.swift
class ViewController: UIViewController { let button = UIBarButtonItem(barButtonSystemItem: .add, target: nil, action: nil) override func viewDidLoad() { super.viewDidLoad() let searchBar = UISearchBar() searchBar.searchBarStyle = .minimal navigationItem.titleView = searchBar } override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) if traitCollection.horizontalSizeClass == .regular { navigationItem.leftBarButtonItem = button } else { navigationItem.leftBarButtonItem = nil } } }
环境:Xcode9.2,iOS11.2.2
我的问题是:有没有办法让 UINavigationBar 正确布局项目,或者我在这里做错了什么?谢谢!
尝试DispatchQueue.main.async
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
DispatchQueue.main.async {
if self.traitCollection.horizontalSizeClass == .regular {
self.navigationItem.leftBarButtonItem = self.button
} else {
self.navigationItem.leftBarButtonItem = nil
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: false)
navigationController?.setNavigationBarHidden(false, animated: true)
}
重置 viewWillAppear
中的 navigationItem.titleView
。
设置 titleView = nil
并返回搜索栏以强制强制导航栏重新布局。
类似于:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.titleView = nil
navigationItem.titleView = self.searchBar
}
更多详情
我喜欢使用 traitCollectionDidChange
的公认解决方案。
但是,该解决方案不适用于(并且仅适用于!)iPhone 11 Pro Max(目前iOS 14.4)。
这是一个非常奇怪的问题,但 viewWillAppear
中的重置是我发现适用于所有设备的唯一可靠解决方案。