50

On ios13, with iphone x, the large title navigation does not cover the status bar however when scrolling and transitioning into the traditional nav bar, it works perfectly. This doesn't affect devices without the notch.

Large titles enter image description here

Traditional navigation bar

It's all embedded within a navigation controller so i'm lost as to why this is happening. Cheers

McDonal_11
  • 3,935
  • 6
  • 24
  • 55
Harry J
  • 1,842
  • 3
  • 12
  • 28

3 Answers3

102

The official way to customize the UINavigationBar, pre iOS 13, is this:

// text/button color
UINavigationBar.appearance().tintColor = .white
// background color
UINavigationBar.appearance().barTintColor = .purple
// required to disable blur effect & allow barTintColor to work
UINavigationBar.appearance().isTranslucent = false

iOS 13 has changed how navigation bars work, so you'll need to do things slightly differently to support both old & new:

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

    UINavigationBar.appearance().tintColor = .white
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().compactAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
} else {
    UINavigationBar.appearance().tintColor = .white
    UINavigationBar.appearance().barTintColor = .purple
    UINavigationBar.appearance().isTranslucent = false
}
Sebastian
  • 1,419
  • 1
  • 16
  • 24
  • 1
    Changed to the correct answer as its slightly more conventional and is more reliant. Thanks – Harry J Jul 15 '19 at 02:27
  • Have you by any chance figured out how to change the color of the back button array? I can change the color of the title by setting the `foregroundColor`, but that doesn't change the color of the arrow (or any other button with an icon for that matter). – Koen. Sep 02 '19 at 09:05
  • This works but now I can't get a translucent nav bar – MobileMon Sep 04 '19 at 13:09
  • @Koen. Good point, the answer didn't include changing the UIBarButtons. I added `UINavigationBar.appearance().tintColor = .white`, which makes that change. – Sebastian Sep 08 '19 at 11:13
  • 1
    @MobileMon What's your current code for a colored-but-translucent nav bar? – Sebastian Sep 08 '19 at 11:14
  • @Sebastian I was actually looking for a solution that would allow me to have different tint colors based on the type of appearance (scroll edge, standard, compact). – Koen. Sep 08 '19 at 20:18
  • @Koen. As far as I _know_, that's not supported by default. – Sebastian Sep 09 '19 at 21:03
  • @Sebastian - You made my day. Thanks! – geohei Sep 30 '19 at 15:22
  • Using this approach, how would I be able to adjust, for instance, the title y position in the standard navigation bar, using navigationController?navigationBar.setTitleVerticalPositionAdjustment(4.0, for: .default) doesn't work in this case. – nontomatic Oct 15 '19 at 20:08
  • @MobileMon Did you managed to make nav bar translucent in ios13 ? – user3626411 Jan 02 '20 at 14:03
  • 1
    @user3626411 if you want to mimic apple's translucent nav bar, just remove this line "UINavigationBar.appearance().barTintColor = MyColor ": https://mobilemon.code.blog/2019/10/11/how-to-make-your-uinavigationbar-look-like-apples-in-ios-13/ – MobileMon Jan 02 '20 at 14:27
15

Use my extension iOS 13 Swift 5 tested

extension UIViewController {
func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
    if #available(iOS 13.0, *) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.backgroundColor = backgoundColor

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

        navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.tintColor = tintColor
        navigationItem.title = title

    } else {
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = backgoundColor
        navigationController?.navigationBar.tintColor = tintColor
        navigationController?.navigationBar.isTranslucent = false
        navigationItem.title = title
    }
}}

How to use:

configureNavigationBar(largeTitleColor: .yourColor, backgoundColor: .yourColor, tintColor: .yourColor, title: "yuorTitle", preferredLargeTitle: true)

Set ViewController-based status bar...... to NO in info.plist if you want light Content

If you don't want largeTitles set it to false

for tranlsucent change navBarAppearance.configureWithOpaqueBackground() in:

navBarAppearance.configureWithDefaultBackground()
navigationController?.navigationBar.isTranslucent = true

in the call set background color to .clear

UPDATE: If you want to start with navigation controller and large Titles at first controller, don't forget to set launch controller in Scene Delegate like this:

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
let vC = UINavigationController(rootViewController: YourFirstViewController())
window?.rootViewController = vC

hope this help :)

Fabio
  • 5,432
  • 4
  • 22
  • 24
1

For full application navigation bar support please add this extension inside your code.

import UIKit
extension UIViewController {


    open func showNavigationBar(_ large: Bool,
                                _ animated: Bool,
                                titleColor: UIColor,
                                barTintColor: UIColor,
                                fontSize: CGFloat) {

        navigationController?.navigationBar.barTintColor = barTintColor
        navigationController?.navigationBar.backgroundColor = barTintColor
        navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.setNavigationBarHidden(false, animated: animated)
        if large {
            self.navigationController?.navigationBar.prefersLargeTitles = true
            if #available(iOS 13.0, *) {
                let appearance = UINavigationBarAppearance()
                appearance.backgroundColor = barTintColor
                appearance.titleTextAttributes = [.foregroundColor: titleColor]
                appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor,
                                                       NSAttributedString.Key.font: UIFont(resource: R.font.robotoMedium, size: fontSize)!]

                navigationController?.navigationBar.standardAppearance = appearance
                navigationController?.navigationBar.compactAppearance = appearance
                navigationController?.navigationBar.scrollEdgeAppearance = appearance
            } else {
                self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor,
                                                                                     NSAttributedString.Key.font: UIFont(resource: R.font.robotoMedium, size: fontSize)!]
            }
        } else {
            self.navigationController?.navigationBar.prefersLargeTitles = false
            self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor,
                                                                            NSAttributedString.Key.font: UIFont(resource: R.font.robotoMedium, size: 20.0)!]
        }
    }
}

And Then call this method simply

self.showNavigationBar(true, true, titleColor: UIColor.blue, barTintColor: UIColor.red, fontSize: 32.0)
Kiran Sarvaiya
  • 1,318
  • 1
  • 13
  • 37