Search code examples
iosuitableviewuiscrollviewuinavigationcontrolleruinavigationbar

My navigation bar is not moving up when scrolling UITableView with background image


I have this view hierarchy on a view embedded in a UINavigationController:

enter image description here

When I scroll the UITableView the navigation bar is not moving up (the title is not becoming smaller) it stays like this:

enter image description here

If I remove the image view as background view everything works well.

enter image description here

My navigation is configured like this:

navigationItem.title = "Title here"
navigationItem.largeTitleDisplayMode = .always

navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.isTranslucent = true
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.barStyle = UIBarStyle.blackTranslucent
navigationController?.navigationBar.backgroundColor = .clear

A project demonstrating the problem is available here: https://drive.google.com/file/d/181Aggala2ZfGN0lDjEtHWg0vobkM0iJc/view?usp=sharing

I already tried to change the insets of the tableview but it didn't work.

tableView.contentInset = UIEdgeInsets(top: navigationController?.navigationBar.height, left: 0, bottom: 0, right: 0)

Thanks!


Solution

  • As you discovered, to make large title fonts work as you want them to, the UIScrollView or any of its subclass needs to be the first element in the view hierarchy.

    To fix your problem, you can try setting the background image to be the background of the UITableView directly.

    Edit: Okay soo according to your comment you want a background behind everything including navigation bar. There is one way of achieving this and that is to subclass your UINavigationController and inside viewDidLoad:

    override func viewDidLoad() {
       super.viewDidLoad()
    
       let image = UIImage(named: "wallpaper")
       let imageView = UIImageView(image: image)
       imageView.contentMode = .scaleAspectFill
    
       imageView.frame = UIScreen.main.bounds
       //this below part is important. Make sure to set it to 0 otherwise it will cover everything else
       view.insertSubview(imageView, at: 0)
    }
    

    And then make sure your UIViewController containing the UITableView has a clear color for the UIView and remove the background image from that UIViewController