iOS 16导航栏navigationItem的titleView出现额外空白求助
iOS 16导航栏titleView额外空白/边距异常问题解决方法
在iOS 16环境下给navigationItem设置自定义titleView时,会出现iOS 15不存在的布局异常:
- iOS 15中,titleView距屏幕左右边缘为12pt;
- iOS 16中,titleView距屏幕左右边缘变为20pt,且自定义titleView的frame宽度被系统自动压缩(比如iPhone 13 Pro Max上,设置的404pt宽度被压缩到388pt),导致内部控件错位,破坏预期设计。

用户测试代码(视图控制器嵌套在导航控制器中):
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() navigationItem.titleView = UIView(frame: CGRect(x: 0, y: 0, width: 404, height: 40)) view.backgroundColor = .lightGray titleView.backgroundColor = .red } }
可行解决方法
方法一:通过UINavigationBarAppearance统一调整边距
iOS 16更新了导航栏的布局逻辑,可通过自定义UINavigationBarAppearance覆盖系统默认的title区域边距:
override func viewDidLoad() { super.viewDidLoad() let appearance = UINavigationBarAppearance() // 设置title区域左右内边距为12pt,与iOS15保持一致 appearance.layoutMargins = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12) // 同时应用到普通状态和滚动状态的导航栏 navigationController?.navigationBar.standardAppearance = appearance navigationController?.navigationBar.scrollEdgeAppearance = appearance let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 404, height: 40)) titleView.backgroundColor = .red navigationItem.titleView = titleView view.backgroundColor = .lightGray }
方法二:给titleView添加明确的宽度约束
如果系统自动压缩titleView宽度,可通过Auto Layout强制锁定宽度,避免被修改:
override func viewDidLoad() { super.viewDidLoad() let titleView = UIView() titleView.backgroundColor = .red titleView.translatesAutoresizingMaskIntoConstraints = false // 强制设置宽度和高度 NSLayoutConstraint.activate([ titleView.widthAnchor.constraint(equalToConstant: 404), titleView.heightAnchor.constraint(equalToConstant: 40) ]) navigationItem.titleView = titleView view.backgroundColor = .lightGray }
方法三:用占位按钮抵消额外边距
若导航栏左右无按钮,系统会给titleView预留更多边距,可添加透明占位按钮调整:
override func viewDidLoad() { super.viewDidLoad() // 左侧占位按钮,抵消系统多出来的8pt边距(20-12=8) let leftPlaceholder = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) leftPlaceholder.width = -8 navigationItem.leftBarButtonItems = [leftPlaceholder] // 右侧同理 let rightPlaceholder = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) rightPlaceholder.width = -8 navigationItem.rightBarButtonItems = [rightPlaceholder] let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 404, height: 40)) titleView.backgroundColor = .red navigationItem.titleView = titleView view.backgroundColor = .lightGray }
原理说明
iOS 16对UINavigationBar的布局逻辑进行了调整,默认增大了title区域的左右边距,同时会自动调整titleView的宽度以适配新布局。上述方法通过覆盖系统默认配置、强制约束或占位调整,均可恢复iOS 15时期的titleView布局表现。
内容的提问来源于stack exchange,提问作者s1321222
相关产品推荐
相关产品推荐

