如何为UINavigationController的根控制器与其他控制器设置不同导航栏背景色?
优雅实现导航栏背景色随栈顶控制器变化的方案
针对你提出的导航栏颜色需求,无需逐个控制器手动设置,以下几种方案更简洁可靠:
方案一:借助UINavigationController代理
给导航控制器设置代理,利用代理方法监听控制器切换事件,动态调整导航栏颜色:
Objective-C 代码示例
// 在自定义导航控制器或根控制器中实现 - (void)viewDidLoad { [super viewDidLoad]; self.delegate = self; } #pragma mark - UINavigationControllerDelegate - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { BOOL isRootVC = (viewController == navigationController.viewControllers.firstObject); navigationController.navigationBar.barTintColor = isRootVC ? [UIColor redColor] : [UIColor greenColor]; }
Swift 代码示例
override func viewDidLoad() { super.viewDidLoad() delegate = self } extension CustomNavigationController: UINavigationControllerDelegate { func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { let isRootVC = viewController == navigationController.viewControllers.first navigationController.navigationBar.barTintColor = isRootVC ? .red : .green } }
方案二:自定义UINavigationController
通过重写导航控制器的入栈、出栈方法,每次栈结构变化时自动更新导航栏颜色,逻辑更内聚:
Objective-C 代码示例
@interface CustomNavigationController () @end @implementation CustomNavigationController - (void)viewDidLoad { [super viewDidLoad]; // 初始化时设置根控制器对应颜色 [self updateNavBarColor]; } - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { [super pushViewController:viewController animated:animated]; [self updateNavBarColor]; } - (UIViewController *)popViewControllerAnimated:(BOOL)animated { UIViewController *poppedVC = [super popViewControllerAnimated:animated]; [self updateNavBarColor]; return poppedVC; } - (NSArray<UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated { NSArray *vcs = [super popToRootViewControllerAnimated:animated]; [self updateNavBarColor]; return vcs; } - (NSArray<UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated { NSArray *vcs = [super popToViewController:viewController animated:animated]; [self updateNavBarColor]; return vcs; } #pragma mark - 私有方法 - (void)updateNavBarColor { BOOL isRootVC = (self.topViewController == self.viewControllers.firstObject); self.navigationBar.barTintColor = isRootVC ? [UIColor redColor] : [UIColor greenColor]; } @end
Swift 代码示例
class CustomNavigationController: UINavigationController { override func viewDidLoad() { super.viewDidLoad() updateNavBarColor() } override func pushViewController(_ viewController: UIViewController, animated: Bool) { super.pushViewController(viewController, animated: animated) updateNavBarColor() } override func popViewController(animated: Bool) -> UIViewController? { let poppedVC = super.popViewController(animated: animated) updateNavBarColor() return poppedVC } override func popToRootViewController(animated: Bool) -> [UIViewController]? { let vcs = super.popToRootViewController(animated: animated) updateNavBarColor() return vcs } override func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? { let vcs = super.popToViewController(viewController, animated: animated) updateNavBarColor() return vcs } private func updateNavBarColor() { let isRootVC = topViewController == viewControllers.first navigationBar.barTintColor = isRootVC ? .red : .green } }
方案三:UIViewController分类(轻量场景)
通过给UIViewController添加分类,利用生命周期方法统一处理导航栏颜色,注意需确保所有控制器都调用super.viewWillAppear::
Objective-C 代码示例
@interface UIViewController (NavBarColor) @end @implementation UIViewController (NavBarColor) - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; UINavigationController *nav = self.navigationController; if (!nav) return; BOOL isRootVC = (self == nav.viewControllers.firstObject); nav.navigationBar.barTintColor = isRootVC ? [UIColor redColor] : [UIColor greenColor]; } @end
Swift 代码示例
extension UIViewController { open override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) guard let nav = navigationController else { return } let isRootVC = self == nav.viewControllers.first nav.navigationBar.barTintColor = isRootVC ? .red : .green } }
内容的提问来源于stack exchange,提问作者ximmyxiao
相关产品推荐
相关产品推荐

