#iOS 11 Xcode 9 Navigation bar height not changes

#iOS 11 Xcode 9 Navigation bar height not changes

and also status bar is not hidden getting 20 px space at the bottom of the navigation bar


self.navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: (self.navigationController?.navigationBar.frame.size.width)!, height: 116)

I'm changing bar height by override the

func sizeThatFits(_ size: CGSize) -> CGSize


example:

let navigationNormalHeight: CGFloat = 44
let navigationExtendHeight: CGFloat = 84

extension UINavigationBar {
    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        var barHeight: CGFloat = navigationNormalHeight
    
        if size.height == navigationExtendHeight {
            barHeight = size.height
        }
    
        let newSize: CGSize = CGSize(width: self.frame.size.width, height: barHeight)
        return newSize
    }
}

and change it where I need

self.navigationBar.frame.size = self.navigationBar.sizeThatFits(CGSize(width: self.navigationBar.frame.size.width,
                                                                                               height: 44))

It's correctly change the bar height, but the bar item doesn't to change position like it was in the iOS 10.
I hope it'll helpful

It doesn't work for me

It also don't work for me. Please help!

I'm having the same issue.

In particular the size of the navigation bar content view is changing, but the size of the navigation bar is not. Infact when the autolayout caluclates the views' position, it places the view under the standard navigation bar height. The same code is perfectly working on iOS 10 and on iOS 11 (built from xCode 8.3).

I've solved using this:


if #available(iOS 11.0, *) {
     self.additionalSafeAreaInsets.top = 20
}


in the viewWillAppear of the ViewController extended by all view controllers in my app.


You have to set the additionalSafeAreaInsets.top with your navigationbar height less the standard statusbar height (which is 44).


This is the code of my custom navigationbar.

It seems to work on both iOS 10 and 11 (tested on iPhone X and iPhone 8).


class CustomNavigationBar: UINavigationBar {
  
    // NavigationBar height
    var customHeight : CGFloat = 64
  
    override func sizeThatFits(_ size: CGSize) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
    }
  
    override func layoutSubviews() {
        super.layoutSubviews()
      
        let y = UIApplication.shared.statusBarFrame.height
        frame = CGRect(x: frame.origin.x, y:  y, width: frame.size.width, height: customHeight)
      
        for subview in self.subviews {
            var stringFromClass = NSStringFromClass(subview.classForCoder)
            if stringFromClass.contains("BarBackground") {
                subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)
                subview.backgroundColor = self.backgroundColor
            }
          
            stringFromClass = NSStringFromClass(subview.classForCoder)
            if stringFromClass.contains("BarContent") {
                subview.frame = CGRect(x: subview.frame.origin.x, y: 20, width: subview.frame.width, height: customHeight)
                subview.backgroundColor = self.backgroundColor
            }
        }
    }
}


Hope it helps.

It increased the navigation bar background not increased the actual navigation bar height. Now the bar looks bigger but the views what ever i am having in view controller going behind the bar.

Thank you! This seems to work for me as well.

Same issue here, my controller view top is behind the nav bar. Did you get a fix for this?

Resizing the navigation bar (via any method, including subclassing) is not supported, and neither is changing the frame of a navigation bar that is owned by a UINavigationController (the navigation controller will happily stomp on your frame changes whenever it deems fit to do so).


Also the frame "CGRect(x: 0, y: 0, width: <width>, height: 116)" is wrong. The navigation bar needs to be placed on the bottom edge of the status bar, not underlapping the status bar, and with its natural height. If you were laying out the navigation bar manually, the correct frame in this case would be "CGRect(x: 0, y: 20, width: <width>, height: 96)" (this assumes a 20pt tall status bar, iPhone X uses a 44pt tall status bar).


Finally the internal layout of the navigation bar is an implementation detail *including all class names and orderings*. Any code that relies upon the ordering of the navigation bar's subviews or the names of any of their classes is likely to encounter issues in the future, as these are all private details. Please do not rely upon them.


If there are things you want to do with a navigation bar that you cannot, please Report Bugs!

Thank you for the solution. but now it seems like my view got behind the navigation bar any solution for that?

thanks in advance

Here is the solution add these lines in your view controller ViewDidLoad


if #available(iOS 11.0, *) {

self.additionalSafeAreaInsets.top = (self.navigationController?.navigationBar.frame.size.height)!

}

You don't need to modify the safe area insets to account for the navigation bar, that is already done for you by the navigation controller.


If you want your view controller's view to layout below the navigation bar rather than underlapping the navigation bar, set the view controller's edgesForExtendedLayout property to not include 'top' (it includes all edges by default).

"...as these are all private details. Please do not rely upon them."


So how do we solve this issue without relying upon the private details?

You don't, not if you need to rely upon private implementation details to solve the problem. You instead Report a Bug asking for support for what you are doing.


If you are just trying to get a continuous background with some other UI element you position under the navigation bar, what you can do is instead of trying to resize the navigation bar, you can just customize it to be transperant, then add your own UIVisualEffectView (or whatever other background you want) that underlaps the navigation bar and put your content there.


But without knowing why people are trying to make the navigation bar bigger, we don't know how to support you or that we ever need to. Thats why filing bugs is important.

Makes sense ... I just submitted a bug report explaining why I've been using a custom navigation bar height.


Meanwhile, I found this workaround to (approximately) double the height: https://stackoverflow.com/a/47321141/462162

Here is the solution add these lines in your custom subclass UINagationController.

kTYStatusBarHeight is the statusBar height.

It worked for me as well.

- (void)viewSafeAreaInsetsDidChange {

[super viewSafeAreaInsetsDidChange];

if (self.view.safeAreaInsets.top < kTYStatusBarHeight) {

self.additionalSafeAreaInsets = UIEdgeInsetsMake(kTYStatusBarHeight, 0, 0, 0);

}

}

I would like to increase the height of the navigationBar to put in a segmented control and other items. However, as you suggest this cannot be done. Putting these items under the navigationBar and removing the navigationBar shadow encounters two other significant problems. Firstly when you add a searchController to the navigationBar, the shadow persists and cannot be removed. Secondly, when used with a tableViewController underneath in a containerView, the pull to refresh when rubber banding the navigationBar covers the segmentedControl and other items. I filed a bug and the reply was:


"This specific configuration of subviews and constraints to the safe area, in combination with the large title navigation bar, isn’t supported. Instead of having the label and table view pinned inside the safe area, the table view should extend to the edges of its container view (it should extend outside the safe area, under the navigation bar). This way, the table view will not be resized as it is scrolled and the navigation bar expands or collapses. Then you can use the tableHeaderView property of the table view to display this label at the top, below the navigation bar."


However the tableView headerView is not a practical solution in this case as the header is lost when the user scrolls down. I believe the problem is the items that are being added below the navigationBar and pinned to the safeArea should move down with the navigationBar as it rubberBands on pull to refresh. Incidentally this is the case when the navigationBar rubberBands with largeTitles.

Thanks for response, it's all clear, but how then stock Message app on iOS gets it's navbar bigger for conversation screen? Even with animation on push/pop between dialogs list screen and conversation screen.

It's a private API i guess?

I believe this issue can be solved by using a section header. Of course then you are limited by having only 1 section header in the table view.

#iOS 11 Xcode 9 Navigation bar height not changes
 
 
Q