iOS 8 Swift Xcode 6 - Set top nav bar bg color and height

12,384

Solution 1

Nav bar height:

In a custom navigation controller subclass...

The trick with this one is to NOT change the actual height of the navigation bar and instead adjust its origin.

func viewDidLoad() {
    super.viewDidLoad()

    navigationBar.frame.origin.y = -10 
}

Nav bar bg color in RGB:

In a custom navigation controller subclass...

func viewDidLoad() {
    super.viewDidLoad()

    navigationBar.barTintColor = // YOUR COLOR
}

or use the appearance proxy

UINavigationBar.appearance().barTintColor = // YOUR COLOR

Nav bar centered logo

In a custom view controller...

func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.titleView = UIImageView(image: // YOUR LOGO)
}

Solution 2

After applying the code in the accepted answer, the height doesn't seem to change at all..

It's not an easy job...and I've surveyed several articles online (most of them in Objective-C).

The most useful one is this: http://www.emdentec.com/blog/2014/2/25/hacking-uinavigationbar

But its final solution does not put items in the middle, and it's not in Swift.

So I come up with a workable version in Swift. Hope it helps some people as I was saved so many precious time on SO.

Solution in Swift:

The following code will solve some issues you may have encountered:

  • The title & items are not placed in the middle of the navigation bar
  • The title & items would flick when the user navigates between view controllers

You need to subclass the UINavigationBar first, and in your storyboard, select the navigation bar element, and in the "Identity Inspector" tab, set the new class as the Custom Class

import UIKit

class UINavigationBarTaller: UINavigationBar {
    ///The height you want your navigation bar to be of
    static let navigationBarHeight: CGFloat = 64

    ///The difference between new height and default height
    static let heightIncrease:CGFloat = navigationBarHeight - 44

    override init(frame: CGRect) {
        super.init(frame: frame)
        initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initialize()
    }

    private func initialize() {
        let shift = UINavigationBarTaller.heightIncrease/2

        ///Transform all view to shift upward for [shift] point
        self.transform =
            CGAffineTransformMakeTranslation(0, -shift)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let shift = UINavigationBarTaller.heightIncrease/2

        ///Move the background down for [shift] point
        let classNamesToReposition: [String] = ["_UINavigationBarBackground"]
        for view: UIView in self.subviews {
            if classNamesToReposition.contains(NSStringFromClass(view.dynamicType)) {
                let bounds: CGRect = self.bounds
                var frame: CGRect = view.frame
                frame.origin.y = bounds.origin.y + shift - 20.0
                frame.size.height = bounds.size.height + 20.0
                view.frame = frame
            }
        }
    }

    override func sizeThatFits(size: CGSize) -> CGSize {
        let amendedSize:CGSize = super.sizeThatFits(size)
        let newSize:CGSize = CGSizeMake(amendedSize.width, UINavigationBarTaller.navigationBarHeight);
        return newSize;
    }
} 

Also on my gist: https://gist.github.com/pai911/8fa123d4068b61ad0ff7

iOS 10 Update:

Unfortunately, this code breaks in iOS 10, there is someone who helps fix it, here you go:

iOS 10 custom navigation bar height

And to be clear, this code is kind of hacky since it depends on the navigation bar's internal structure...so if you decide to use it anyway, be prepared for any upcoming changes that may break this code...

Solution 3

Great answer from Bon Bon!

In Swift 3 however make sure you replace

let classNamesToReposition: [String] = ["_UINavigationBarBackground"]

with

let classNamesToReposition: [ String ] = [ "_UIBarBackground" ]

Otherwise, it wont work.

Share:
12,384
Erik Lydecker
Author by

Erik Lydecker

Concept Developer

Updated on June 07, 2022

Comments

  • Erik Lydecker
    Erik Lydecker almost 2 years

    I have looked everywhere and tested all the code snippets posted on Stack, but nothing works for me as I need it to work.

    I simply want to set:

    • Nav bar height
    • Nav bar bg color in RGB
    • Nav bar centered logo

    I'm working with iOS8, Xcode 6 and Swift.

    Many thanks for a clear answer!

    This is my code in ViewController.swift

    // Set nav bar height
    
        navigationController?.navigationBar.frame.origin.y = -10
    
        // Set nav bar bg color
    
        var navBarColor = UIColor(red: 4 / 255, green: 47 / 255, blue: 66 / 255, alpha: 1)
    
        navigationController?.navigationBar.barTintColor = navBarColor
    
        // Set nav bar logo
    
        let navBarImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
    
        navBarImageView.contentMode = .ScaleAspectFit
    
        let navBarImage = UIImage(named: "navBarLogo.png")
    
        navBarImageView.image = navBarImage
    
        navigationItem.titleView = navBarImageView
    
  • Erik Lydecker
    Erik Lydecker about 9 years
    Awesome! I will try this =)
  • DBoyer
    DBoyer about 9 years
    Let me know if you still are having trouble with anything :)
  • Lukesivi
    Lukesivi over 8 years
    Incredible. Great job! Any ideas on how to add an image as a logo in the center of the Navbar? Or text?
  • Lukesivi
    Lukesivi over 8 years
    Ps, mind explaining why you're using all the initialize functions?
  • John the Traveler
    John the Traveler over 8 years
    That will transform all the coordinates of the navigation bar upwards for [shift] points (there are two params in CGAffineTransformMakeTranslation, , the 1st one is for x, the 2nd one is for Y)
  • John the Traveler
    John the Traveler over 8 years
    for adding a logo in the navigation bar, pls see this tutorial: ioscreator.com/tutorials/customizing-navigation-bar-ios8-swi‌​ft
  • WaterNotWords
    WaterNotWords about 8 years
    This does not work reliably. See the link for the reason why. You need to subclass. stackoverflow.com/a/28708356/4577867
  • Vlad Z.
    Vlad Z. over 7 years
    During modal transition it will jump a little, still pretty great answer
  • John the Traveler
    John the Traveler over 7 years
    Thanks for the update! there is also a post with full code sample. stackoverflow.com/questions/39454548/… and I updated my original post, cheeres