Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Messages-like taller / standard navigation bar during push / pop

iOS 10 Messages app's navigation bar increases/decreases the height when you push/pop a conversation (with a smooth transition).

Typically I make a taller custom navigation bar using sizeThatFits:, but it persists across pushes and pops of view controllers in a navigation controller.

How is it possible to have a taller navigation bar just for some view controllers across navigation sequences like the Messages app? Thanks!

like image 751
qfwfq Avatar asked Nov 07 '16 11:11

qfwfq


People also ask

What is navigation bar height iOS?

iPhone X added extra height for the Home Bar to toolbars and tab bars and their sizes are unchanged from iOS 11: 83 points tall in portrait and 53 points tall in landscape.


1 Answers

Very interesting problem. I spent some time to achieve something like this in the Messages app and that is what I've done.

enter image description here

Finally, I use this trick to animate navigationBar height during push/pop and also pop with swipe gesture.

UIView.beginAnimations(nil, context: nil)
self.frame = navFrame
UIView.commitAnimations()

Below you can see my implementation:

extension UINavigationBar {
    func applyHeight(_ height: CGFloat, animated: Bool = true) {
        var navFrame = self.frame
        navFrame.size.height = height
        if animated {
            UIView.beginAnimations(nil, context: nil)
            self.frame = navFrame
            UIView.commitAnimations()
        } else {
            self.frame = navFrame
        }
    }
}

class ViewControllerA: UIViewController {

    override func loadView() {
        super.loadView()
        title = "A"
        view.backgroundColor = .blue
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "NEXT", style: .plain, target: self, action: #selector(self.showController))
        navigationController?.navigationBar.isTranslucent = false
    }

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

    func showController() {
        navigationController?.pushViewController(ViewControllerB(), animated: true)
    }
}

class ViewControllerB: UIViewController {

    override func loadView() {
        super.loadView()
        title = "B"
        view.backgroundColor = .red
    }

    override func viewWillAppear(_ animated: Bool) {
        navigationController?.navigationBar.applyHeight(100)
        super.viewWillAppear(animated)
    }

    override func willMove(toParentViewController parent: UIViewController?) {
        if parent == nil { // here you know that back button was tapped
            navigationController?.navigationBar.applyHeight(44)
        }
        super.willMove(toParentViewController: parent)
    }
}

Things to improve

  • Title jumps to top

Jumping title is visible while you swipe to pop, but personally, I think this is a small problem :)

Hope it helps you, and maybe someone can improve this implementation. Of course, I will still try to figure out how to make this better :) Here it's a github repository. Please use navigation_bar_height branch.

like image 192
kamwysoc Avatar answered Oct 04 '22 17:10

kamwysoc