从视图控制器返回后UINavigationBar的titleTextAttributes未更新
这个问题我之前也碰到过,核心原因是导航栏属于UINavigationController的全局控件,从第二个视图控制器返回时,第一个控制器的viewWillAppear可能没正确触发,或者设置逻辑有遗漏。下面给你几个靠谱的解决方案:
1. 确保viewWillAppear正确执行并调用super
首先检查第一个视图控制器的viewWillAppear方法,必须调用[super viewWillAppear:animated],否则视图生命周期流程可能异常。修改后的代码如下:
- (void)viewWillAppear:(BOOL)animated { // 一定要先调用super,保证生命周期方法正常触发 [super viewWillAppear:animated]; // 设置当前页面的导航栏标题样式 self.navigationController.navigationBar.titleTextAttributes = @{ NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: [UIFont systemFontOfSize:14.0] }; }
第二个视图控制器的viewWillAppear也要遵循这个规则,确保切换过去时样式生效,返回时第一个控制器的设置能覆盖原有样式。
2. 用导航控制器代理集中管理样式
如果项目中有多个页面需要自定义导航栏样式,推荐用UINavigationControllerDelegate集中处理,避免每个控制器重复写代码:
让导航控制器的代理对象(比如AppDelegate或专门的管理类)实现以下方法:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { // 根据即将显示的控制器类型设置对应样式 if ([viewController isKindOfClass:[FirstViewController class]]) { navigationController.navigationBar.titleTextAttributes = @{ NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: [UIFont systemFontOfSize:14.0] }; } else if ([viewController isKindOfClass:[SecondViewController class]]) { navigationController.navigationBar.titleTextAttributes = @{ NSForegroundColorAttributeName: [UIColor blackColor], NSFontAttributeName: [UIFont systemFontOfSize:16.0] }; } }
记得给导航控制器设置代理:self.navigationController.delegate = yourDelegateObject;
3. 封装分类避免重复代码
如果不想写重复的设置逻辑,可以给UIViewController写一个分类,把导航栏样式设置封装成方法:
// UIViewController+NavigationBarStyle.h #import <UIKit/UIKit.h> @interface UIViewController (NavigationBarStyle) - (void)setupNavigationBarTitleWithColor:(UIColor *)color font:(UIFont *)font; @end // UIViewController+NavigationBarStyle.m #import "UIViewController+NavigationBarStyle.h" @implementation UIViewController (NavigationBarStyle) - (void)setupNavigationBarTitleWithColor:(UIColor *)color font:(UIFont *)font { if (!self.navigationController) return; // 提供默认值,避免传nil导致崩溃 UIColor *titleColor = color ?: [UIColor blackColor]; UIFont *titleFont = font ?: [UIFont systemFontOfSize:17.0]; self.navigationController.navigationBar.titleTextAttributes = @{ NSForegroundColorAttributeName: titleColor, NSFontAttributeName: titleFont }; } @end
然后在每个控制器的viewWillAppear里只需要一行代码:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self setupNavigationBarTitleWithColor:[UIColor whiteColor] font:[UIFont systemFontOfSize:14.0]]; }
额外注意:大标题样式的特殊处理
如果你的导航栏用了大标题(self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic;),需要设置largeTitleTextAttributes而不是titleTextAttributes,示例:
self.navigationController.navigationBar.largeTitleTextAttributes = @{ NSForegroundColorAttributeName: [UIColor whiteColor] };
内容的提问来源于stack exchange,提问作者Nicola Giancecchi

