Hemang
Hemang

Reputation: 27050

How to increase height for a custom UINavigationBar class in Swift

Update: I ended up by hiding the default navigation bar and added a UIView which looks same as the navigation bar. This may not sound good but instead of patching into the UINavigationBar this is good.


This is my custom UINavigationBar class which I have created to increase the height of navigation bar in my app. It doesn't work for me. Here's the code.

class PPBaseNavigationBar: UINavigationBar {

    ///The height you want your navigation bar to be of
    static let navigationBarHeight: CGFloat = 83.0

    ///The difference between new height and default height
    static let heightIncrease: CGFloat = navigationBarHeight - 44

    override init(frame: CGRect) {
        super.init(frame: frame)
        initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initialize()
    }

    private func initialize() {
        let shift = PPBaseNavigationBar.heightIncrease/2.0

        ///Transform all view to shift upward for [shift] point
        self.transform = CGAffineTransform(translationX: 0, y: -shift)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let shift = PPBaseNavigationBar.heightIncrease/2.0

        ///Move the background down for [shift] point
        var classNamesToReposition: Array<String>?
        if #available(iOS 10.0, *) {
            classNamesToReposition = ["_UIBarBackground"]
        } else {
            classNamesToReposition =  ["_UINavigationBarBackground"]
        }

        for view: UIView in self.subviews {
            if (classNamesToReposition?.contains(NSStringFromClass(view.classForCoder)))! {
                let bounds: CGRect = self.bounds
                var frame: CGRect = view.frame
                frame.origin.y = bounds.origin.y + shift - 20.0
                frame.size.height = bounds.size.height + 20.0
                view.frame = frame
            }
        }
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        let amendedSize:CGSize = super.sizeThatFits(size)
        let newSize:CGSize = CGSize.init(width: amendedSize.width, height: PPBaseNavigationBar.navigationBarHeight)
        return newSize;
    }
}

All the method gets called except override func sizeThatFits(_ size: CGSize) -> CGSize {...} not sure, why?

Upvotes: 1

Views: 2121

Answers (4)

Karthick Selvaraj
Karthick Selvaraj

Reputation: 2505

Try like this, this worked for me in Swift 3:

extension UINavigationBar {

    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.size.width, height: "Your custom height")   
    }

}


// MARK: - View life cycle methods

class DVNavigationController: UINavigationController {

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        navigationBar.frame.size.height = "Your custom height"
    }

}

Finally assign this custom UINavigationController class to your navigationController.

Upvotes: 1

Lalit kumar
Lalit kumar

Reputation: 2207

layoutSubviews works as well override func sizeThatFits(_ size: CGSize). so do not worry if it is not sizeThatFits called. I checked in layoutSubviews Navigationbar height are changing.

for view: UIView in self.subviews {
        if (classNamesToReposition?.contains(NSStringFromClass(view.classForCoder)))! {
            let bounds: CGRect = self.bounds
            var frame: CGRect = view.frame
            frame.origin.y = bounds.origin.y + shift - 20.0
            frame.size.height = bounds.size.height + 150.0
            view.frame = frame
        }
    }

Upvotes: 1

Torongo
Torongo

Reputation: 1091

It is not permissible to change the navigation bar object or modify its bounds, frame, or alpha values directly. 

Modifying the Navigation Bar Object Directly

You can use custom view as navigation bar. Customize view as per your requirement(e.g change height) and hide the default navigation bar as

self.navigationController?.setNavigationBarHidden(true, animated: false)

Upvotes: 3

Govaadiyo
Govaadiyo

Reputation: 6082

Change your code like below

open override func sizeThatFits(_ size: CGSize) -> CGSize {
        let amendedSize:CGSize = super.sizeThatFits(size)
        let newSize:CGSize = CGSize.init(width: amendedSize.width, height: PPBaseNavigationBar.navigationBarHeight)
        return newSize;
    }

Might be worked for you.

Upvotes: 0

Related Questions