在Swift中更改导航栏颜色

314

我正在使用一个选择器视图来允许用户选择整个应用程序的颜色主题。

我计划更改导航栏、背景和可能的选项卡栏(如果可能)的颜色。

我一直在研究如何做到这一点,但找不到任何Swift示例。请问是否有人可以给我提供代码示例,以便我可以更改导航栏颜色和导航栏文本颜色?

选择器视图已设置好,我只是在寻找更改UI颜色的代码。

36个回答

634
导航栏:
navigationController?.navigationBar.barTintColor = UIColor.green

用您想要的任何UIColor替换greenColor,如果您喜欢,也可以使用RGB。

导航栏文本:

navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.orange]

用你喜欢的颜色替换orangeColor。

选项卡栏:

tabBarController?.tabBar.barTintColor = UIColor.brown

选项卡文本:

tabBarController?.tabBar.tintColor = UIColor.yellow

在最后两个中,用您选择的颜色替换brownColor和yellowColor。


2
更新到新的Xcode beta版本后,设置标题文本颜色不再起作用。在Swift中不可用titleTextAttributes。有什么想法吗? - user3746428
1
你能开一个新的问题并附上链接吗?聊天不是这样讨论的最佳场所。 - trumpeter201
3
我发现它让我使用NSForegroundColorAttributeName作为属性名称,但除此之外,一切都很好。 - Jake Hall
NSForegroundColorAttributeName是什么? - LLIAJLbHOu
能否通过同一视图上的按钮更改导航栏颜色?我尝试过了,但似乎不可能。 - Nicholas
显示剩余8条评论

111

以下是可以在整个应用程序中应用的一些非常基本的外观自定义:

UINavigationBar.appearance().backgroundColor = UIColor.greenColor()
UIBarButtonItem.appearance().tintColor = UIColor.magentaColor()
//Since iOS 7.0 UITextAttributeTextColor was replaced by NSForegroundColorAttributeName
UINavigationBar.appearance().titleTextAttributes = [UITextAttributeTextColor: UIColor.blueColor()]
UITabBar.appearance().backgroundColor = UIColor.yellowColor();

Swift 5.4.2:

UINavigationBar.appearance().backgroundColor = .green // backgorund color with gradient
// or
UINavigationBar.appearance().barTintColor = .green  // solid color
    
UIBarButtonItem.appearance().tintColor = .magenta
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.blue]
UITabBar.appearance().barTintColor = .yellow

关于在Swift中使用UIAppearance API的更多信息,请阅读这里


那么我该如何使用它来更改整个应用程序的导航栏颜色呢?目前我只有:self.navigationController.navigationBar.barTintColor = UIColor.newBlueColor()当然,这只会更改代码所在的视图控制器的导航栏颜色。我该如何使用它来更改所有导航栏呢?我尝试使用:UINavigationBar.appearance().backgroundColor = UIColor.newBlueColor()但似乎没有任何作用。 - user3746428
6
为了反映整个应用程序中的更改,请将上述代码粘贴到AppDelegate.swift文件中的以下方法中:func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // 将上述代码放置在此处 } - Badrinath
8
使用barTintColor代替backgroundColor。UINavigationBar.appearance().barTintColor = UIColor.greenColor()。 (翻译: Use barTintColor instead of backgroundColor. UINavigationBar.appearance().barTintColor = UIColor.greenColor()) - Michael Peterson
@Keenle 我有点困惑...为什么通过外观API更改UINavigationBar的背景颜色不会完全改变它的颜色?我尝试将背景颜色设置为蓝色,但它给了我一种奇怪的紫蓝色调... - fja

73

更新至Swift 3、4、4.2、5+版本

// setup navBar.....
UINavigationBar.appearance().barTintColor = .black
UINavigationBar.appearance().tintColor = .white
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
UINavigationBar.appearance().isTranslucent = false

Swift 4

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

Swift 4.2,5+

UINavigationBar.appearance().barTintColor = .black
UINavigationBar.appearance().tintColor = .white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UINavigationBar.appearance().isTranslucent = false

如果您想使用大标题,可以添加这一行代码:

UINavigationBar.navigationBar.prefersLargeTitles = true

也可以在这里检查:https://github.com/hasnine/iOSUtilitiesSource


1
Swift 4.2: NSAttributedString.Key.foregroundColor - Kasra Babaei
我无法更改我的投票!太可怕了!上面的回答对我不起作用。我后悔我投了正面评价,但我无法取消我的投票。这个其他答案对我有用:https://stackoverflow.com/questions/60795035/bartintcolor-not-applied-when-navigationbar-is-large-titles - Markus
@Markus,你有什么问题吗?为什么你投了票之后又试图反对票!向我们提问,我们会为你找到解决方案的兄弟 :) - Jamil Hasnine Tamim
2
@Markus 哦哦,很遗憾!再试一次吧兄弟。 - Jamil Hasnine Tamim
2
在设置了 UINavigationBar.appearance().prefersLargeTitles = true 后,这段代码不起作用了,请问如何解决? - Zhou Haibo
显示剩余6条评论

52
UINavigationBar.appearance().barTintColor = UIColor(red: 46.0/255.0, green: 14.0/255.0, blue: 74.0/255.0, alpha: 1.0)
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()]

只需将此行粘贴到您代码的didFinishLaunchingWithOptions 方法中。


我尝试了使用RGB,但无论我把它放在哪里都不起作用。 - Nathan McKaskle
@NathanMcKaskle 请检查您的RGB值,它应该是“xx/250.0f”格式。 - Mohit Tomar
在didFinishLaunchingWithOptions中使用时完美运行。在viewDidLoad中不完美运行。 - Touhid

28

AppDelegate 中,这已全局更改了 NavBar 的格式并移除了底部线条/边框(这是大多数人的问题区域),以便为您和其他人提供我认为您正在寻找的内容:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default)
    UINavigationBar.appearance().shadowImage = UIImage()
    UINavigationBar.appearance().tintColor = UIColor.whiteColor()
    UINavigationBar.appearance().barTintColor = Style.SELECTED_COLOR
    UINavigationBar.appearance().translucent = false
    UINavigationBar.appearance().clipsToBounds = false
    UINavigationBar.appearance().backgroundColor = Style.SELECTED_COLOR
    UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName : (UIFont(name: "FONT NAME", size: 18))!, NSForegroundColorAttributeName: UIColor.whiteColor()] }

那么您可以设置一个 Constants.swift 文件,其中包含一个Style结构体,其中包括颜色、字体等。您可以将tableView/pickerView添加到任何ViewController中,并使用"availableThemes"数组允许用户更改themeColor。

这个美妙的地方在于,您可以在整个应用程序中使用一个引用来表示每个颜色,它将基于用户选择的"主题"进行更新,如果没有默认为theme1():

import Foundation
import UIKit

struct Style {


static let availableThemes = ["Theme 1","Theme 2","Theme 3"]

static func loadTheme(){
    let defaults = NSUserDefaults.standardUserDefaults()
    if let name = defaults.stringForKey("Theme"){
        // Select the Theme
        if name == availableThemes[0]   { theme1()  }
        if name == availableThemes[1]   { theme2()  }
        if name == availableThemes[2]   { theme3()  }
    }else{
        defaults.setObject(availableThemes[0], forKey: "Theme")
        theme1()
    }
}

 // Colors specific to theme - can include multiple colours here for each one
static func theme1(){
   static var SELECTED_COLOR = UIColor(red:70/255, green: 38/255, blue: 92/255, alpha: 1) }

static func theme2(){
    static var SELECTED_COLOR = UIColor(red:255/255, green: 255/255, blue: 255/255, alpha: 1) }

static func theme3(){
    static var SELECTED_COLOR = UIColor(red:90/255, green: 50/255, blue: 120/255, alpha: 1) } ...

2
谢谢,你的回答真的帮了我很多。至少对我来说,我使用了其中的第一部分,它非常棒和有用。 - Ameer Fares
1
非常感谢您,我尝试了这里的每个答案,除了您的答案以外都无法生效 :D - Ronak Shah

23

在Storyboard上完成此操作(使用Interface Builder Inspector)

通过IBDesignable,我们可以为UINavigationController添加更多选项,并在Storyboard上进行微调。首先,将以下代码添加到您的项目中。

@IBDesignable extension UINavigationController {
    @IBInspectable var barTintColor: UIColor? {
        set {
            guard let uiColor = newValue else { return }
            navigationBar.barTintColor = uiColor
        }
        get {
            guard let color = navigationBar.barTintColor else { return nil }
            return color
        }
    }
}

然后只需在Storyboard上设置导航控制器的属性。

enter image description here

这种方法也可用于从Storyboard中管理导航栏文本的颜色:

@IBInspectable var barTextColor: UIColor? {
  set {
    guard let uiColor = newValue else {return}
    navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: uiColor]
  }
  get {
    guard let textAttributes = navigationBar.titleTextAttributes else { return nil }
    return textAttributes[NSAttributedStringKey.foregroundColor] as? UIColor
  }
}

喜欢它。虽然我不认为这对OP有用,但对于从Google访问的访客来说,这是一个很好的解决方案。 - Psiloc

22

Swift 4:

完美运行的代码,用于在应用程序级别更改导航栏外观。

在此输入图片描述

// MARK: Navigation Bar Customisation

// To change background colour.
UINavigationBar.appearance().barTintColor = .init(red: 23.0/255, green: 197.0/255, blue: 157.0/255, alpha: 1.0)

// To change colour of tappable items.
UINavigationBar.appearance().tintColor = .white

// To apply textAttributes to title i.e. colour, font etc.
UINavigationBar.appearance().titleTextAttributes = [.foregroundColor : UIColor.white,
                                                    .font : UIFont.init(name: "AvenirNext-DemiBold", size: 22.0)!]
// To control navigation bar's translucency.
UINavigationBar.appearance().isTranslucent = false

快乐编程!


18

以下代码适用于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
    }

这个应该有100个赞 :) 谢谢! - Tung Fam

17
UINavigationBar.appearance().barTintColor

对我很有用。


17

SWIFT 4 - 平滑过渡(最佳解决方案):

如果您从导航控制器返回并且必须在推出的导航控制器上设置不同的颜色,您应该使用

override func willMove(toParentViewController parent: UIViewController?) {
    navigationController?.navigationBar.barTintColor = .white
    navigationController?.navigationBar.tintColor = Constants.AppColor
}

将其放在viewWillAppear中会导致过渡效果不够流畅,建议使用其他方式。

SWIFT 4.2

override func willMove(toParent parent: UIViewController?) {
    navigationController?.navigationBar.barTintColor = UIColor.black
    navigationController?.navigationBar.tintColor = UIColor.black
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接