如何在所有场景中设置导航栏背景颜色

Posted

技术标签:

【中文标题】如何在所有场景中设置导航栏背景颜色【英文标题】:How to set navigation bar background color across all scenes 【发布时间】:2018-04-18 07:33:18 【问题描述】:

我有一个带有 5 个选项卡的选项卡式视图。我还有一个导航栏,并使用以下代码更改其背景颜色:

//Change navigation colors
viewController.navigationController?.navigationBar.barTintColor = UIColor.orange
viewController.navigationController?.navigationBar.tintColor = UIColor.white
viewController.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]

每个选项卡都有自己的视图控制器,因此我没有将相同的代码放在viewDidLoad() 方法中,而是创建了一个具有静态方法setupNavigation(viewController: UIViewController) 的类UIHelper。所以viewDidLoad()方法的每个viewController中我只是调用方法

UIHelper.setupNavigation(viewController: self)

有没有更简单的方法来改变导航栏背景的全局颜色?

我正在使用 Swift 4。

编辑:实际上我有一个MasterViewController,并且标签的每个视图控制器都扩展了它。所以UIHelper.setupNavigationMasterViewControllerviewDidDLoad() 中被调用。

【问题讨论】:

【参考方案1】:

您有很多方法可以做到这一点: 第一 创建一个 superViewController 并且所有其他视图控制器都继承这个:

import UIKit

class SuperViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()

        self.navigationController?.navigationBar.barTintColor = UIColor.orange
        self.navigationController?.navigationBar.tintColor = UIColor.white
        self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

其他类似的视图控制器:

class ViewController: SuperViewController 

    @IBOutlet weak var pageVC: UIView!
    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

现在您不需要在应用程序中设置导航颜色,只需在每个视图控制器中使用继承 superViewcontroller。您可以在每个控制器中添加您将要遵循的所有常用方法。

第二种方法

///Common NavigationController for every controller used in application
class NavigationController: UINavigationController 

    // MARK: - View Lifecycle
    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.navigationBar.barTintColor = UIColor.red
        self.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

在您的应用中随处使用此导航控制器。当你需要 导航控制器然后在导航控制器中给出这个类。

【讨论】:

是的,我有一个 MasterViewController,UIHelper.setupNavigation(viewController: self) 被放入它的viewDidLoad()。我猜另一个答案建议“更全球化”和“准确”的方式来做到这一点。我将阅读更多内容。谢谢你的回答 请在您的应用程序中使用通用导航控制器。我已经更新了我的答案。请看一下【参考方案2】:

您可以使用导航栏代理类(将设置转发到所有导航栏),例如在 AppDelegate 的方法 didFinishLaunchingWithOptions 中运行:

UINavigationBar.appearance().barTintColor = UIColor.orange
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]

【讨论】:

这个答案与导航栏有关,与状态栏无关。【参考方案3】:

我想建议您另一种方法来做到这一点。我认为它更加通用和灵活。 所以我建议你只是UINavigationController 的子类。您可以在项目中拥有任意数量的实现。您可以从代码中初始化此类,也可以在 Storyboard 文件中设置适当的类。

import UIKit

class CustomNavigationController: UINavigationController 

    override func viewDidLoad() 
        super.viewDidLoad()

        //Change navigation colors
        self.navigationBar.barTintColor = UIColor.orange
        self.navigationBar.tintColor = UIColor.white
        self.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    

    //this method allow you to ask each controller for status bar style in navigation stack
    override var childViewControllerForStatusBarStyle: UIViewController? 
        return self.topViewController
    


在您的视图控制器类中,您也应该覆盖此属性

import UIKit

class ViewController: UIViewController 

    override var preferredStatusBarStyle: UIStatusBarStyle 
        return .lightContent
    


【讨论】:

【参考方案4】:

为了支持暗模式和 swift5,请在 AppDelegate 中使用:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 

 UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: .green]
    
    if #available(ios 13.0, *) 
        if UITraitCollection.current.userInterfaceStyle == .dark 
            UINavigationBar.appearance().barTintColor = .black
         else 
            UINavigationBar.appearance().barTintColor = .white
        
     else 
        UINavigationBar.appearance().barTintColor = .white
    

...
return true

【讨论】:

【参考方案5】:

以下代码适用于 iOS 15 *

if #available(iOS 15, *) 
    // Navigation Bar background color
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor.yourColor
    
    // setup title font color
    let titleAttribute = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 25, weight: .bold), NSAttributedString.Key.foregroundColor: UIColor.yourColor]
    appearance.titleTextAttributes = titleAttribute
    
    navigationController?.navigationBar.standardAppearance = appearance
    navigationController?.navigationBar.scrollEdgeAppearance = appearance

【讨论】:

以上是关于如何在所有场景中设置导航栏背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

转到下一个视图会更改导航栏背景颜色

iOS中设置导航栏标题的字体颜色和大小

FLEX:如何在Flare3d中设置场景的背景颜色?

如何在OpenGL中设置背景颜色

在 Swift 中设置活动标签栏项目的背景颜色

未设置反应本机状态栏背景颜色