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

设置UINavigationBar大标题后滚动时仍缩小,如何始终保持大标题?

导航栏大标题滚动时保持大尺寸的问题解决思路

问题复盘

  • 已完成配置:导航控制器设置prefersLargeTitles = true,表视图控制器设置navigationItem.largeTitleDisplayMode = .always
  • 异常现象:初始显示符合预期,但向上滚动时标题仍会缩小并移至顶部栏项目旁
  • 尝试过的无效方案:
    • 将UITableViewController嵌入UIViewController的容器视图
    • 在UIViewController中直接使用UITableView
    • 在UITableView上方添加0高度UIView(此操作会丢失标题的弹跳和缩放效果)
  • 特殊表现:静态UITableViewController可正常维持大标题,但子UITableViewController无法实现

临时解决方案(保留标题动画效果)

如果需要保留大标题的弹跳和缩放动画,同时避免滚动时缩小,可尝试以下两种方法:

方法1:拦截滚动事件强制维持大标题

给UITableView添加滚动监听,强制保持导航栏的大标题状态:

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    
    navigationController?.navigationBar.prefersLargeTitles = true
    navigationItem.largeTitleDisplayMode = .always
    
    // 监听滚动偏移变化
    tableView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard keyPath == "contentOffset" else { return }
    // 强制刷新导航栏状态,维持大标题
    navigationController?.navigationBar.sizeToFit()
    navigationItem.setLargeTitleDisplayMode(.always)
}

deinit {
    tableView.removeObserver(self, forKeyPath: "contentOffset")
}

注意:此方法可能存在轻微视觉抖动,需根据实际场景调整。

方法2:自定义导航栏标题视图

完全脱离系统大标题逻辑,用自定义UILabel模拟大标题效果:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 隐藏系统默认标题
    navigationItem.title = ""
    
    // 创建自定义大标题标签
    let largeTitleLabel = UILabel()
    largeTitleLabel.text = "你的标题文本"
    largeTitleLabel.font = UIFont.preferredFont(forTextStyle: .largeTitle).withTraits(traits: .traitBold)
    largeTitleLabel.textColor = .label
    
    // 将标签作为左侧BarButtonItem添加到导航栏
    navigationItem.leftBarButtonItem = UIBarButtonItem(customView: largeTitleLabel)
    
    // 配置约束,确保标签位置符合大标题布局
    largeTitleLabel.translatesAutoresizingMaskIntoConstraints = false
    guard let navBar = navigationController?.navigationBar else { return }
    NSLayoutConstraint.activate([
        largeTitleLabel.centerYAnchor.constraint(equalTo: navBar.centerYAnchor),
        largeTitleLabel.leadingAnchor.constraint(equalTo: navBar.leadingAnchor, constant: 16)
    ])
}

// 扩展UIFont,添加便捷的加粗方法
extension UIFont {
    func withTraits(traits: UIFontDescriptor.SymbolicTraits) -> UIFont {
        guard let descriptor = fontDescriptor.withSymbolicTraits(traits) else { return self }
        return UIFont(descriptor: descriptor, size: 0)
    }
}

此方法可完全控制标题样式与行为,不受滚动影响,但如需弹跳/缩放动画,需自行实现。

关于UIKit Bug的说明

根据测试结果,静态UITableViewController正常但子UITableViewController异常,这大概率是UIKit内部逻辑问题。在已向Apple提交反馈的前提下,建议:

  • 关注后续iOS版本更新,确认问题是否修复
  • 反馈时附上测试项目,帮助Apple更快定位问题

内容的提问来源于stack exchange,提问作者Mof

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:48:28