You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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),导致内部控件错位,破坏预期设计。

iOS16与iOS15导航栏titleView对比

用户测试代码(视图控制器嵌套在导航控制器中):

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:17:49