22

Can some one tell me how to change the navigation bar height?

Here is what i have so far:

CGFloat navBarHeight = 10;
self.navigationController.navigationBar.frame.size.width = navBarHeight;
Piper
  • 1,266
  • 3
  • 15
  • 26

12 Answers12

25

You can create a category class based on UINavigationBar like this

.h file

#import UIKit/UIKit.h    
@interface UINavigationBar (myNave)
- (CGSize)changeHeight:(CGSize)size;
@end

and .m file

#import "UINavigationBar+customNav.h"
@implementation UINavigationBar (customNav)
- (CGSize)sizeThatFits:(CGSize)size {
    CGSize newSize = CGSizeMake(320,100);
    return newSize;
}
@end

It works very nice.

wallyk
  • 56,922
  • 16
  • 83
  • 148
Shimon Wiener
  • 1,142
  • 4
  • 18
  • 39
  • this works but moves the UINavigationItem to the top, the title and the items are no more center aligned horizontally – Anand Oct 30 '12 at 13:36
  • @Anand : Same problem is there any solution for this? – Ashvin Oct 17 '14 at 06:34
  • 1
    To recenter the title use `[self.navigationBar setTitleVeritcalPositionAdjustment:(float) forBarMetrics:UIBarMetricsDefault];` where `float` is a positive value to push the title down and a negative value to push it back up. So if you're nav bar was 44 (default) and you make it 60, set `float` to -8 ((60-44)/2) to recenter it – Mr.P May 25 '16 at 08:49
21

You should not change the height of the navigation bar. From Apple Programing Guide on View Controller:

Customizing the Navigation Bar Appearance

In a navigation interface, a navigation controller owns its UINavigationBar object and is responsible for managing it. It is not permissible to change the navigation bar object or modify its bounds, frame, or alpha values directly. However, there are a few properties that it is permissible to modify, including the following:

● barStyle property

● translucent property

● tintColor property

(taken from Apple: https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html)

-- UPDATE -- IOS 7 --- still only the available properties can be changed but below is a great tutorial on how to achieve flexibility in the navigation bar http://www.appcoda.com/customize-navigation-status-bar-ios-7/

Gil Margolin
  • 1,959
  • 20
  • 21
8

I have solved this issue, I created the subclass of UINavigationController. In this MainNavigationViewController.m file I rewrite viewDidLayoutSubviews() method, where I set the frame for self.navigationBar

Yerkezhan
  • 481
  • 5
  • 9
8

sizeThatFits: no longer works with iOS11 UINavigationBar subclasses. Apple Engineering have confirmed that this technique was never supported and with iOS11 changes sizeThatFits: is no longer consulted.

ghr
  • 505
  • 4
  • 8
6

Override -(void)viewWillAppear method in the viewController and Try the code below,

- (void)viewWillAppear {

UINavigationBar *navigationBar = [[self navigationController] navigationBar];
CGRect frame = [navigationBar frame];
frame.size.height = 82.0f;
[navigationBar setFrame:frame];
}
Augustine P A
  • 5,008
  • 3
  • 35
  • 39
  • 1
    Close, but this will overlap the underlying view instead of shifting it. – rwyland Mar 08 '13 at 00:26
  • 1
    It might be because of your navigationbar style. If it is translucent type, then it will overlap the views. I think if it is opaque, then subviews may shifted down automatically. – Augustine P A Mar 13 '13 at 13:35
  • 2
    Nope, the first 44px will be fine on opaque, but everything after is overlapped. I also found out that the navigationBar frame will reset on screen rotation or on app resume (viewWillAppear isn't called on app resume). So sadly this hack just won't work correctly. – rwyland Mar 13 '13 at 15:47
5

Try using -

CGFloat navBarHeight = 10.0f;    
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, navBarHeight);
[self.navigationController.navigationBar setFrame:frame];
Cliff Viegas
  • 3,216
  • 1
  • 18
  • 10
  • 4
    Doesn't actually change anything. I tried to set the frame when I create the UINavigationController in my AppDelegate. There's no error message or anything, but the nav bar height doesn't change at all. Tested with Xcode 4.4 and iOS 4.3, 5.0, 5.1. – jcsahnwaldt Reinstate Monica Sep 29 '13 at 19:46
4

Most Simple and Effective Solution is to add a category to navigation bar. (but maybe not the best solution)

@interface UINavigationBar (CustomHeight)

@end


@implementation UINavigationBar (CustomHeight)

- (CGSize)sizeThatFits:(CGSize)size {
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    return CGSizeMake(screenRect.size.width, kNavBarHeightNoStatus);
}
@end

knavBarHeightNoStatus is the height of your navbar. We use UIScreen bounds because frame of UINavigationBar is wrong

PS: Be careful, you can have some issues using it with a SideMenu

Beninho85
  • 3,273
  • 27
  • 22
3

self.navigationController.navigationBar.frame is a readonly property on iOS version 4.x

it will be changed even though, you will see abnormal behavior.

for example, when app state changed to background and get back to foreground the Navigation bar will show original sized height

agf
  • 171,228
  • 44
  • 289
  • 238
tachikoma
  • 31
  • 1
2

I ran into a lot of problems depending on the method chosen. In my specific case, the navigation bar was hidden throughout the app except in the Settings View Controller. As I needed to specify a custom height of the navigation bar and show the navigation bar at the same time, the segue between the source view controller and the Settings View Controller had a very sloppy animation.

The absolute best solution can be found here: https://gist.github.com/maciekish/c2c903d9b7e7b583b4b2. I just imported the category into the Settings View Controller, and in viewDidLoad called the setHeight: method on `self.navigationController.navigationBar'. Looks great!

Josh Gafni
  • 2,831
  • 2
  • 19
  • 32
1

Following code won't affect other parameters in frame except height

 [self.navigationController.navigationBar setFrame:CGRectMake(self.navigationController.navigationBar.frame.origin.x, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, 150)];

if you want change other parameters means, just edit the any one of the parameters....

abdul sathar
  • 2,395
  • 2
  • 28
  • 38
0

Try this code inside - (void)viewDidLayoutSubviews method,

CGFloat navBarHeight = 10.0f;    
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, navBarHeight);
[self.navigationController.navigationBar setFrame:frame];
Group
  • 325
  • 1
  • 4
  • 16
0

Creating category and overriding sizeThatFits(_ size: CGSize) -> CGSize method changes UINavigationBar size all over the app. Assuming you want to change UINavigationBar height/size only in one particular ViewController (in my case)

This is how I did it.

extension UINavigationBar {
    open override func sizeThatFits(_ size: CGSize) -> CGSize {
        let v = self.value(forKey: "frame") as? CGRect
        return v?.size ?? CGSize(width: UIScreen.main.bounds.width, height: 44)
    }
}

in caller ViewController would look like

override func viewDidLoad() {
    super.viewDidLoad()
    configureNavigationBar()
}

private func configureNavigationBar() {
    var naviBarFrame = self.navigationController?.navigationBar.frame
    naviBarFrame?.size.height = 74
    let rect = naviBarFrame ?? CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 74)
    self.navigationController?.navigationBar.setValue(rect, forKey: "frame")
}
Chamira Fernando
  • 6,836
  • 3
  • 23
  • 23