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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:32:03