Search code examples
iosswiftuinavigationbar

Swift UINavigationBar background image does not cover status bar when clipToBounds is true


I'm setting the background image of a large title navigation bar like this:

override func viewDidLoad() {
    super.viewDidLoad()
    
    navigationController?.navigationBar.prefersLargeTitles = true
    
    self.title = "Nav bar"
    
    let largeTitleAppearance = UINavigationBarAppearance()
    
    largeTitleAppearance.configureWithOpaqueBackground()
    largeTitleAppearance.backgroundImage = UIImage(named: "kunal-shinde--f0YLss50Bs-unsplash")
    largeTitleAppearance.backgroundImageContentMode = .scaleAspectFill
    largeTitleAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
    largeTitleAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
    
    navigationController?.navigationBar.standardAppearance = largeTitleAppearance
    navigationController?.navigationBar.scrollEdgeAppearance = largeTitleAppearance
}

However, the image overflows out of the navigation bar as shown here:

enter image description here

I thought clipsToBounds might work so I set it to true at the end of viewDidLoad

navigationController?.navigationBar.clipsToBounds = true

enter image description here

This is better, but the image does not cover the status bar! How can I get it to cover the status bar while not overflowing?


Solution

  • We've solved this as followed:

    We set the background image on ViewController. This is the same as we use in navigation bar.

    let imageView = UIImageView(image: .assetImage(.background))
    imageView.contentMode = .topLeft
    collectionView.backgroundView = imageView
    

    Style the navigation bar.

    // General Styling
    UINavigationBar.appearance().tintColor = .assetColor(.navigationBarTintColor)
            
    // Bar Styling
    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.shadowColor = .clear
    navBarAppearance.backgroundColor = UIColor(patternImage: .assetImage(.background)!)
            
    UINavigationBar.appearance().standardAppearance = navBarAppearance
    UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
    

    In addition we change the translucent of the navigation bar for non-root views:

    if isRootview {
        self.navigationController?.navigationBar.isTranslucent = true
    } else {
        self.navigationController?.navigationBar.isTranslucent = false
    }