Messages-like taller / standard navigation bar during push / pop
Asked Answered
S

2

17

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!

Silvia answered 7/11, 2016 at 11:58 Comment(3)
Have you managed to find a solution? I built a UINavigationBar extension for settings a height value and using that value for computing the sizeThatFits frame. Now I can use this extension to update the height on viewWillAppear, by setting the navigationBar height inside an animation loop and calling navigationBar.sizeToFit(). Works great when pushing, unfortunately not so great when popping back. Tried reseting the frame in the same way on viewWillDissapear or on viewWillAppear for the previous controller.Citify
Any progress, guys?Concelebrate
@user370773 You can check my edited answer. I changed the way that I animate navigationBar height. It works for swipe and pop button.Rodolphe
R
7

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.

Rodolphe answered 14/7, 2017 at 11:32 Comment(4)
Thanks for the answer! It looks quite a good approach! The only problem though is that the titleLabel and backButtonTitleLabel jump to top as soon as the transition begins. I guess you need to apply some offset to them as well.Fastigium
Yeah, you're right the title offset is kind of a problem too. I'll try to fix that also. I'll update my answer if I get something new in my solution. :)Rodolphe
I used to override layoutSubviews of my navigation bar when i customize navigationbar's height. just move all subview upper.Bargello
it seems that this answer is no longer working on iOS 11+Highclass
A
0

I think now you can achieve something similar with just this, just set large title to always:

enter image description here

Ani answered 18/12, 2019 at 11:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.