如何解决返回根ViewController后UINavigationBar标题字体恢复默认的问题?
解决导航栏标题样式返回后失效的问题
这个问题其实是因为UINavigationBar是导航控制器共享的实例——你在第二个VC中设置默认样式时,修改的是同一个导航栏的属性。返回根VC时,虽然viewWillAppear会触发,但可能因为代码里的强制解包或者状态覆盖问题导致样式没被正确应用。下面给你几个可靠的解决方法:
方法一:完善根VC的viewWillAppear代码,避免强制解包
你当前的代码用了!强制解包字体,万一字体加载异常(比如字体文件没正确引入项目),这行代码会直接崩溃,返回时也可能因为可选链调用的隐性问题导致样式失效。改成可选绑定更安全,同时确保每次进入都能稳定设置样式:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 先调用super,确保导航栏基础状态正确 if let zapfinoFont = UIFont(name: "Zapfino", size: 18) { self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedString.Key.font: zapfinoFont ] } else { // 字体加载失败时的降级处理,用系统默认字体 self.navigationController?.navigationBar.titleTextAttributes = nil } }
方法二:在第二个VC中精准控制样式(推荐)
既然导航栏是共享的,更优雅的做法是让第二个VC只在自己显示时用默认样式,离开时主动恢复根VC的样式:
在第二个VC中添加:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 仅当前VC显示时,设置默认标题样式 self.navigationController?.navigationBar.titleTextAttributes = nil } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 返回时恢复根VC的标题样式 if let rootVC = self.navigationController?.viewControllers.first as? YourRootVCClass { rootVC.setupNavigationBarStyle() } }
然后在根VC中把设置样式的代码抽成独立方法,方便调用:
func setupNavigationBarStyle() { if let zapfinoFont = UIFont(name: "Zapfino", size: 18) { self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedString.Key.font: zapfinoFont ] } } // 在viewWillAppear中调用这个方法 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setupNavigationBarStyle() }
方法三:用导航控制器代理统一管理(进阶)
如果你的项目里有多个VC需要不同的导航栏样式,可以通过导航控制器的代理来自动切换,不用在每个VC里重复写代码:
// 让根VC遵守UINavigationControllerDelegate协议 extension YourRootVCClass: UINavigationControllerDelegate { func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { if viewController is YourRootVCClass { // 即将显示根VC时,设置对应的标题样式 if let zapfinoFont = UIFont(name: "Zapfino", size: 18) { navigationController.navigationBar.titleTextAttributes = [NSAttributedString.Key.font: zapfinoFont] } } else { // 显示其他VC时,用默认样式 navigationController.navigationBar.titleTextAttributes = nil } } } // 记得在根VC的viewDidLoad中设置代理 override func viewDidLoad() { super.viewDidLoad() self.navigationController?.delegate = self }
这样每次导航控制器切换页面时,都会自动匹配对应VC的导航栏样式,彻底避免样式串位的问题。
内容的提问来源于stack exchange,提问作者Parth Rudakia
相关产品推荐
相关产品推荐

