312

I am using a Picker View to allow the user to choose the colour theme for the entire app.

I am planning on changing the colour of the navigation bar, background and possibly the tab bar (if that is possible).

I've been researching how to do this but can't find any Swift examples. Could anyone please give me an example of the code I would need to use to change the navigation bar colour and navigation bar text colour?

The Picker View is set up, I'm just looking for the code to change the UI colours.

pkamb
  • 33,281
  • 23
  • 160
  • 191
user3746428
  • 11,047
  • 20
  • 81
  • 137

36 Answers36

634

Navigation Bar:

navigationController?.navigationBar.barTintColor = UIColor.green

Replace greenColor with whatever UIColor you want, you can use an RGB too if you prefer.

Navigation Bar Text:

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

Replace orangeColor with whatever color you like.

Tab Bar:

tabBarController?.tabBar.barTintColor = UIColor.brown

Tab Bar Text:

tabBarController?.tabBar.tintColor = UIColor.yellow

On the last two, replace brownColor and yellowColor with the color of your choice.

Simon Bengtsson
  • 7,573
  • 3
  • 58
  • 87
trumpeter201
  • 8,487
  • 3
  • 18
  • 24
111

Here are some very basic appearance customization that you can apply app wide:

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

More about UIAppearance API in Swift you can read here.

Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
Keenle
  • 12,010
  • 3
  • 37
  • 46
  • So how would I use this to change the colour of the navigation bar for the entire app? At the moment I just have: self.navigationController.navigationBar.barTintColor = UIColor.newBlueColor() and of course this just changes the colour of the navigation bar of the view controller that the code is within. How can I use it to change all navigation bars? I tried using: UINavigationBar.appearance().backgroundColor = UIColor.newBlueColor() but it doesn't seem to do anything. – user3746428 Jul 11 '14 at 00:46
  • 6
    To reflect chnages in the entier app , paste the above in below method of AppDelegate.swift func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { //Place above code } – Badrinath Feb 01 '15 at 05:32
  • 8
    Use barTintColor instead of backgroundColor. UINavigationBar.appearance().barTintColor = UIColor.greenColor() – Michael Peterson Mar 11 '15 at 18:48
  • @Keenle I am a bit confused... Why does't changing the background color of the UINavigationBar through the appearance API change its color entirely? I tried to set the background color to blue and it gave me a weird shade of purplish blue... – fja Nov 29 '16 at 03:36
73

Updated for 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

if you want to work with large title, add this line:

UINavigationBar.navigationBar.prefersLargeTitles = true

Also can check here : https://github.com/hasnine/iOSUtilitiesSource

Jamil Hasnine Tamim
  • 4,389
  • 27
  • 43
  • 1
    Swift 4.2: NSAttributedString.Key.foregroundColor – Kasra Babaei Nov 02 '18 at 15:51
  • setting tint color to white rather than bartintcolor shows the original color. Great! – NickCoder Jan 17 '20 at 12:30
  • @NickCoder appreciate it. :) also check my lib: https://github.com/hasnine/iOSUtilitiesSource – Jamil Hasnine Tamim Jan 19 '20 at 04:51
  • I can not change my vote! Horrible! Above answer not working for me. I regret that I voted positively but I cannot cancel my vote. This other answer working for me: https://stackoverflow.com/questions/60795035/bartintcolor-not-applied-when-navigationbar-is-large-titles – Markus Sep 22 '20 at 08:03
  • @Markus what's your issue! Why you voted and after that you are trying to down vote! Ask us, we will find a solution for you bro :) – Jamil Hasnine Tamim Sep 22 '20 at 15:43
  • I downvoted because the solution not worked for me. I simply wanted to remove my previous positive vote. Time ago it was possible, in Stackoverflow.com. Now, no. Pity! – Markus Sep 24 '20 at 07:55
  • 2
    @Markus ohho sad! try again brother. – Jamil Hasnine Tamim Sep 24 '20 at 10:12
  • 2
    This is not worked after put large title on it `UINavigationBar.appearance().prefersLargeTitles = true`, may I know how to fix it? – Zhou Haibo Jan 11 '21 at 12:01
  • @ChuckZHB It's should work! Please check this apple link: https://developer.apple.com/documentation/uikit/uinavigationcontroller/customizing_your_app_s_navigation_bar – Jamil Hasnine Tamim Jan 13 '21 at 05:12
  • @Jamil Hasnine Tamim, I put an answer https://stackoverflow.com/a/65667081/10158398 about how to use it in `large title` mode. – Zhou Haibo Jan 15 '21 at 15:55
  • @ChuckZHB nice! and same code I think. And I added large title code in my answer. Thanks. – Jamil Hasnine Tamim Jan 16 '21 at 08:57
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()]

Just paste this line in didFinishLaunchingWithOptions in your code.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Mohit Tomar
  • 5,173
  • 2
  • 33
  • 40
28

Within AppDelegate, this has globally changed the format of the NavBar and removes the bottom line/border (which is a problem area for most people) to give you what I think you and others are looking for:

 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()] }

Then you can setup a Constants.swift file, and contained is a Style struct with colors and fonts etc. You can then add a tableView/pickerView to any ViewController and use "availableThemes" array to allow user to change themeColor.

The beautiful thing about this is you can use one reference throughout your whole app for each colour and it'll update based on the user's selected "Theme" and without one it defaults to 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) } ...
David West
  • 1,550
  • 1
  • 18
  • 31
23

To do this on storyboard (Interface Builder Inspector)

With help of IBDesignable, we can add more options to Interface Builder Inspector for UINavigationController and tweak them on storyboard. First, add the following code to your project.

@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
        }
    }
}

Then simply set the attributes for navigation controller on storyboard.

enter image description here

This approach may also be used to manage the color of the navigation bar text from the 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
  }
}
Dale
  • 5,520
  • 4
  • 43
  • 79
Fangming
  • 24,551
  • 6
  • 100
  • 90
  • Love it. While I don't think this would work for OP it is an excellent solution for visitors from Google (like me). – Psiloc Jul 24 '20 at 10:59
22

Swift 4:

Perfectly working code to change the navigation bar appearance at application level.

enter image description here

// 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

Happy Coding!

Gaurav Singla
  • 2,271
  • 26
  • 43
18

Below Codes are working for 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
    }
Symon
  • 633
  • 6
  • 15
17
UINavigationBar.appearance().barTintColor

worked for me

Carl0s1z
  • 4,683
  • 7
  • 32
  • 47
Asbar
  • 391
  • 3
  • 14
17

SWIFT 4 - Smooth transition (best solution):

If you're moving back from a navigation controller and you have to set a diffrent color on the navigation controller you pushed from you want to use

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

instead of putting it in the viewWillAppear so the transition is cleaner.

SWIFT 4.2

override func willMove(toParent parent: UIViewController?) {
    navigationController?.navigationBar.barTintColor = UIColor.black
    navigationController?.navigationBar.tintColor = UIColor.black
}
user1872384
  • 6,886
  • 11
  • 61
  • 103
ricks
  • 3,154
  • 31
  • 51
13

Swift 5 (iOS 14)

Full navigation bar customization.

// -----------------------------------------------------------
// NAVIGATION BAR CUSTOMIZATION
// -----------------------------------------------------------
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationController?.navigationBar.isTranslucent = false

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithDefaultBackground()
    appearance.backgroundColor = UIColor.blue
    appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
    appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

    navigationController?.navigationBar.standardAppearance = appearance
    navigationController?.navigationBar.scrollEdgeAppearance = appearance
    navigationController?.navigationBar.compactAppearance = appearance

} else {
    self.navigationController?.navigationBar.barTintColor = UIColor.blue
    self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
    self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
}

// -----------------------------------------------------------
// NAVIGATION BAR SHADOW
// -----------------------------------------------------------
self.navigationController?.navigationBar.layer.masksToBounds = false
self.navigationController?.navigationBar.layer.shadowColor = UIColor.black.cgColor
self.navigationController?.navigationBar.layer.shadowOffset = CGSize(width: 0, height: 2)
self.navigationController?.navigationBar.layer.shadowRadius = 15
self.navigationController?.navigationBar.layer.shadowOpacity = 0.7
Markus
  • 1,147
  • 16
  • 26
11

In Swift 4

You can change the color of navigation bar. Just use this below code snippet in viewDidLoad()

Navigation Bar color

self.navigationController?.navigationBar.barTintColor = UIColor.white

Navigation Bar Text Color

self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.purple]

For iOS 11 Large Title Navigation Bar, you need to use largeTitleTextAttributes property

self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.purple]
Vinoth Vino
  • 9,166
  • 3
  • 66
  • 70
11

Swift 5, an easy approach with UINavigationController extension. At the bottom of this answer are extensions and previews.

First view controller (Home):

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    navigationController?.setTintColor(.white)
    navigationController?.backgroundColor(.orange)
}

Second view controller (Details):

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.transparentNavigationBar()
    navigationController?.setTintColor(.black)
}

Extensions for UINavigationController:

extension UINavigationController {
    func transparentNavigationBar() {
        self.navigationBar.setBackgroundImage(UIImage(), for: .default)
        self.navigationBar.shadowImage = UIImage()
        self.navigationBar.isTranslucent = true
    }

    func setTintColor(_ color: UIColor) {
        self.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: color]
        self.navigationBar.tintColor = color
    }

    func backgroundColor(_ color: UIColor) {
        navigationBar.setBackgroundImage(nil, for: .default)
        navigationBar.barTintColor = color
        navigationBar.shadowImage = UIImage()
    }
}

Storyboard view:

enter image description here

Previews:

enter image description here

Egzon P.
  • 4,498
  • 3
  • 32
  • 31
10

The appearance() function not always work for me. So I prefer to create a NC object and change its attributes.

var navBarColor = navigationController!.navigationBar
navBarColor.barTintColor =
    UIColor(red:  255/255.0, green: 0/255.0, blue: 0/255.0, alpha: 100.0/100.0)
navBarColor.titleTextAttributes =
    [NSForegroundColorAttributeName: UIColor.whiteColor()]

Also if you want to add an image instead of just text, that works as well

var imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 70, height: 70))
imageView.contentMode = .ScaleAspectFit

var image = UIImage(named: "logo")
imageView.image = image
navigationItem.titleView = imageView
LionHere
  • 9
  • 1
  • 2
GuiSoySauce
  • 1,763
  • 3
  • 24
  • 37
  • with that way, I was able to change self.navigationController?.navigationBar.topItem?.title color. Thank u. – oguzhan Nov 14 '19 at 09:16
9

Use the appearance API, and barTintColor color.

UINavigationBar.appearance().barTintColor = UIColor.greenColor()
Michael Peterson
  • 10,383
  • 3
  • 54
  • 51
8

In iOS 15, UIKit has extended the usage of the scrollEdgeAppearance, which by default produces a transparent background, to all navigation bars. Set scrollEdgeAppearance as below code.

if #available(iOS 15, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = < your tint color >
        navigationController?.navigationBar.standardAppearance = appearance;
        navigationController?.navigationBar.scrollEdgeAppearance = navigationController?.navigationBar.standardAppearance
    } 
sufian
  • 191
  • 2
  • 5
6

This version also removes the 1px shadow line under the navigation bar:

Swift 5: Put this in your AppDelegate didFinishLaunchingWithOptions

UINavigationBar.appearance().barTintColor = UIColor.black
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UINavigationBar.appearance().isTranslucent = false
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
tuvok
  • 185
  • 2
  • 10
4

iOS 8 (swift)

let font: UIFont = UIFont(name: "fontName", size: 17)   
let color = UIColor.backColor()
self.navigationController?.navigationBar.topItem?.backBarButtonItem?.setTitleTextAttributes([NSFontAttributeName: font,NSForegroundColorAttributeName: color], forState: .Normal)
Yogesh Suthar
  • 30,424
  • 18
  • 72
  • 100
Long Pham
  • 7,464
  • 3
  • 29
  • 40
4

If you have customized navigation controller, you can use above code snippet. So in my case, I've used as following code pieces.

Swift 3.0, XCode 8.1 version

navigationController.navigationBar.barTintColor = UIColor.green

Navigation Bar Text:

navigationController.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.orange]

It is very helpful talks.

Joe
  • 8,868
  • 8
  • 37
  • 59
4

Swift 4, iOS 12 and Xcode 10 Update

Just put one line inside viewDidLoad()

navigationController?.navigationBar.barTintColor = UIColor.red
Xcodian Solangi
  • 2,342
  • 5
  • 24
  • 52
4

iOs 14+

init() {        
    let appearance = UINavigationBarAppearance()
    appearance.shadowColor = .clear // gets also rid of the bottom border of the navigation bar
    appearance.configureWithTransparentBackground() 
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
Hellcaraxe
  • 65
  • 1
  • 1
  • 5
  • Where do you set color here? It does not really answer the question. – Moose Mar 08 '21 at 16:14
  • according to https://developer.apple.com/documentation/uikit/uibarappearance/3197998-configurewithopaquebackground it's available since iOS 13 – Lex Aug 11 '22 at 13:49
4

None of the solutions worked for me so I'm sharing the one that did.

Swift 5, Xcode 13.4.1

Put the below inside the viewDidLoad():

let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = UIColor.systemBlue
        appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
        navigationItem.standardAppearance = appearance
        navigationItem.scrollEdgeAppearance = appearance
        navigationItem.compactAppearance = appearance

This is the result

enter image description here

Remember to set all settings in the inspector to default. In case you need more adjustments search via Developers Documentation "Customizing Your App’s Navigation Bar"

Hope that helps.

Dimple
  • 788
  • 1
  • 11
  • 27
Bsheskee
  • 51
  • 3
3

In Swift 2

For changing color in navigation bar,

navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

For changing color in item navigation bar,

navigationController?.navigationBar.tintColor = UIColor.blueColor()

or

navigationController!.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.blueColor()]
Abhijeet
  • 8,561
  • 5
  • 70
  • 76
Riccardo Caroli
  • 341
  • 1
  • 3
  • 12
3

Swift 3

UINavigationBar.appearance().barTintColor = UIColor(colorLiteralRed: 51/255, green: 90/255, blue: 149/255, alpha: 1)

This will set your navigation bar color like Facebook bar color :)

Community
  • 1
  • 1
Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
3

Swift 3

Simple one liner that you can use in ViewDidLoad()

//Change Color
    self.navigationController?.navigationBar.barTintColor = UIColor.red
//Change Text Color
    self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
Codetard
  • 2,441
  • 28
  • 34
3

Swift 3 and Swift 4 Compatible Xcode 9

A Better Solution for this to make a Class for common Navigation bars

I have 5 Controllers and each controller title is changed to orange color. As each controller has 5 navigation controllers so i had to change every one color either from inspector or from code.

So i made a class instead of changing every one Navigation bar from code i just assign this class and it worked on all 5 controller Code reuse Ability. You just have to assign this class to Each controller and thats it.

import UIKit

   class NabigationBar: UINavigationBar {
      required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
    commonFeatures()
 }

   func commonFeatures() {

    self.backgroundColor = UIColor.white;
      UINavigationBar.appearance().titleTextAttributes =     [NSAttributedStringKey.foregroundColor:ColorConstants.orangeTextColor]

 }


  }
OurangZeb Khan
  • 1,114
  • 18
  • 20
3

If you're using iOS 13 or 14 and large title, and want to change navigation bar color, use following code:

Refer to barTintColor not applied when NavigationBar is Large Titles

    fileprivate func setNavigtionBarItems() {
        if #available(iOS 13.0, *) {
            let appearance = UINavigationBarAppearance()
            appearance.configureWithDefaultBackground()
            appearance.backgroundColor = .brown
//            let naviFont = UIFont(name: "Chalkduster", size: 30) ?? .systemFont(ofSize: 30)
//            appearance.titleTextAttributes = [NSAttributedString.Key.font: naviFont]
            
            navigationController?.navigationBar.prefersLargeTitles = true
            navigationController?.navigationBar.standardAppearance = appearance
            navigationController?.navigationBar.scrollEdgeAppearance = appearance
            //navigationController?.navigationBar.compactAppearance = appearance
        } else {
            // Fallback on earlier versions
            navigationController?.navigationBar.barTintColor = .brown
        }
    }

This took me 1 hour to figure out what is wrong in my code:(, since I'm using large title, it is hard to change the tintColor with largeTitle, why apple makes it so complicated, so many lines to just make a tintColor of navigationBar.

Machavity
  • 30,841
  • 27
  • 92
  • 100
Zhou Haibo
  • 1,681
  • 1
  • 12
  • 32
2

iOS 10 Swift 3.0

If you don't mind to use swift frameworks then us UINeraida to change navigation background as UIColor or HexColor or UIImage and change navigation back button text programmatically, change complete forground text color.

For UINavigationBar

    neraida.navigation.background.color.hexColor("54ad00", isTranslucent: false, viewController: self)
    
    //Change navigation title, backbutton colour
    
    neraida.navigation.foreground.color.uiColor(UIColor.white, viewController: self)
    
    //Change navigation back button title programmatically
    
    neraida.navigation.foreground.backButtonTitle("Custom Title", ViewController: self)
    
    //Apply Background Image to the UINavigationBar
    
    neraida.navigation.background.image("background", edge: (0,0,0,0), barMetrics: .default, isTranslucent: false, viewController: self)
Community
  • 1
  • 1
1

I had to do

UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().barStyle = .Black
UINavigationBar.appearance().backgroundColor = UIColor.blueColor()

otherwise the background color wouldn't change

1

First set the isTranslucent property of navigationBar to false to get the desired colour. Then change the navigationBar colour like this:

@IBOutlet var NavigationBar: UINavigationBar!

NavigationBar.isTranslucent = false
NavigationBar.barTintColor = UIColor (red: 117/255, green: 23/255, blue: 49/255, alpha: 1.0)
Nupur Sharma
  • 1,106
  • 13
  • 15
1

Make sure to set the Button State for .normal

extension UINavigationBar {

    func makeContent(color: UIColor) {
        let attributes: [NSAttributedString.Key: Any]? = [.foregroundColor: color]

        self.titleTextAttributes = attributes
        self.topItem?.leftBarButtonItem?.setTitleTextAttributes(attributes, for: .normal)
        self.topItem?.rightBarButtonItem?.setTitleTextAttributes(attributes, for: .normal)
    }
}

P.S iOS 12, Xcode 10.1

Mazen Kasser
  • 3,559
  • 2
  • 25
  • 35
  • 1
    Thank you. I have been searching for hours for this `topItem` solution. It's frustrating the number of changes Apple continue to make to how styles are applied to the navigation. – App Dev Guy Mar 30 '20 at 14:10
1

Try This in AppDelegate:

//MARK:- ~~~~~~~~~~setupApplicationUIAppearance Method
func setupApplicationUIAppearance() {

    UIApplication.shared.statusBarView?.backgroundColor = UIColor.clear

    var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

    UINavigationBar.appearance().tintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    UINavigationBar.appearance().barTintColor =  UIColor.white
    UINavigationBar.appearance().isTranslucent = false

    let attributes: [NSAttributedString.Key: AnyObject]

    if DeviceType.IS_IPAD{
        attributes = [
            NSAttributedString.Key.foregroundColor: UIColor.white,
            NSAttributedString.Key.font: UIFont(name: "HelveticaNeue", size: 30)
            ] as [NSAttributedString.Key : AnyObject]
    }else{
        attributes = [
            NSAttributedString.Key.foregroundColor: UIColor.white
        ]
    }
    UINavigationBar.appearance().titleTextAttributes = attributes
}

iOS 13

func setupNavigationBar() {
    //        if #available(iOS 13, *) {
    //            let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
    //            let statusBar = UIView(frame: window?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero)
    //            statusBar.backgroundColor = #colorLiteral(red: 0.2784313725, green: 0.4549019608, blue: 0.5921568627, alpha: 1) //UIColor.init(hexString: "#002856")
    //            //statusBar.tintColor = UIColor.init(hexString: "#002856")
    //            window?.addSubview(statusBar)
    //            UINavigationBar.appearance().tintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    //            UINavigationBar.appearance().barTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    //            UINavigationBar.appearance().isTranslucent = false
    //            UINavigationBar.appearance().backgroundColor = #colorLiteral(red: 0.2784313725, green: 0.4549019608, blue: 0.5921568627, alpha: 1)
    //            UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
    //        }
    //        else
    //        {
    UIApplication.shared.statusBarView?.backgroundColor = #colorLiteral(red: 0.2784313725, green: 0.4549019608, blue: 0.5921568627, alpha: 1)
    UINavigationBar.appearance().tintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    UINavigationBar.appearance().barTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    UINavigationBar.appearance().isTranslucent = false
    UINavigationBar.appearance().backgroundColor = #colorLiteral(red: 0.2784313725, green: 0.4549019608, blue: 0.5921568627, alpha: 1)
    UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
    //        }
}

Extensions

extension UIApplication {

var statusBarView: UIView? {
    if responds(to: Selector(("statusBar"))) {
        return value(forKey: "statusBar") as? UIView
    }
    return nil
}}
Tej Patel
  • 119
  • 2
  • 5
1

simply call the this extension and pass the color it will automatically change the color of nav bar

extension UINavigationController {
    
     func setNavigationBarColor(color : UIColor){
            self.navigationBar.barTintColor = color
        }
    }

in the view didload or in viewwill appear call

self.navigationController?.setNavigationBarColor(color: <#T##UIColor#>)
Machavity
  • 30,841
  • 27
  • 92
  • 100
Talha Rasool
  • 1,126
  • 14
  • 12
1

I'm writing this for those that still have problems with the solutions here.

I'm using Xcode Version 11.4 (11E146). The one working for me is:

navigationController?.navigationBar.barTintColor = UIColor.white
navigationController?.navigationBar.tintColor = UIColor.black

BUT!, if you set the barTintColor in storyboard to any other value than "default" this 2 lines of code will have no effect.

So, be carefull and set back to default barTintColor in Storyboard. Oh Apple...

Tomas
  • 866
  • 16
  • 21
  • Still same problem despite changing tint colour to default :( – marika.daboja Apr 17 '20 at 05:06
  • @marika.daboja All your navigation controllers in storyboard are set to default colors? – Tomas Apr 17 '20 at 08:54
  • Hi, I only have 1 Navigation Controller (plus 2 Table View Controllers). Navigation Controller Bar Tint colour is set to 'default'. Code I have to update this colour seems to not have an affect on it. – marika.daboja Apr 20 '20 at 02:59
  • @marika.daboja make sure you that navigationController is not nil. And that you put this lines of code in viewDidLoad() – Tomas Apr 20 '20 at 16:21
-1

My two cents:

a) setting navigationBar.barTintColor / titleTextAttributes do work in any view (pushed, added..and so on in init..

b) setting appearence does not work everywhere:

  • You can call it on AppDelegate
  • " " 1st level view
  • if You call it again in subsequent pushed views, does MNOT work

SwiftUI note:

a) does not apply (no navigationBar, unless you pass via UIViewControllerRepresentable trick..) b) is valid for SwiftUI: same behaviour.

ingconti
  • 10,876
  • 3
  • 61
  • 48
-1

I'm working in Xcode 14.1 for iOS 16.1

I had to change the scrollEdgeAppearance to actually change the color of the navBar. The background color was only making a really translucent color even if I had disabled the translucent property.

So it went like this:

navigationController?.navigationBar.scrollEdgeAppearance = UIColor.*/your_color/*