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

Swift 5:通过扩展无法设置UINavigationController大标题

问题根源与修复方案

嘿,这个问题其实是踩了一个很容易忽略的小坑——你搞混了UINavigationController实例里navigationController属性的含义!

为什么扩展没生效?

你写的扩展是给UINavigationController本身添加的方法,当你在这个方法里调用navigationController?时,你其实是在问这个导航控制器自己的父导航控制器是谁。但导航控制器本身就是顶层的导航容器,它的navigationController属性永远是nil!所以那行关键的navigationController?.navigationBar.prefersLargeTitles = true相当于完全没执行,自然看不到效果。

而你直接在ViewController的viewDidLoad里写navigationController?.navigationBar...时,这里的navigationController是当前ViewController所属的导航控制器(也就是你要配置的那个),它是有值的,所以代码能正常工作。

另外还有一个小问题:你在扩展里设置的navigationItem.title是导航控制器自己的导航项,不是你当前显示的子控制器的,就算前面的代码生效了,标题也不会显示在你期望的位置。

修复后的扩展代码

我们需要把扩展里的错误引用修正,直接操作导航控制器本身,同时针对当前顶部的子控制器设置标题:

extension UINavigationController { 
    func configureLargeTitle(with title: String) { 
        // 直接操作当前导航控制器的导航栏,开启大标题
        navigationBar.prefersLargeTitles = true 
        // 给当前显示的子控制器设置标题和大标题显示模式
        topViewController?.navigationItem.title = title 
        topViewController?.navigationItem.largeTitleDisplayMode = .automatic 
    } 
}

更合适的写法(可选)

如果你只是想给单个子控制器配置大标题,其实给UIViewController写扩展会更直观,这样在子控制器里调用起来更自然:

extension UIViewController {
    func setupLargeTitle(with title: String) {
        // 拿到当前控制器所属的导航控制器,开启大标题
        navigationController?.navigationBar.prefersLargeTitles = true
        // 设置当前控制器自己的导航项
        navigationItem.title = title
        navigationItem.largeTitleDisplayMode = .automatic
    }
}

调用的时候直接在子控制器的viewDidLoad里写:

setupLargeTitle(with: "我的页面标题")

总结

核心问题就是你在UINavigationController的扩展里错误地使用了navigationController?(这个属性对它自己来说是nil),导致关键的配置代码没执行。修正后就能正常开启大标题效果啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:07:51