update for iOS 11 and beyond
apple doesn't want you messing with the navigation bar height, so don't touch it
see here: https://openradar.appspot.com/32912789
and here: https://forums.developer.apple.com/thread/88202#274620
class TallerNaviBar: UINavigationBar {
override func sizeThatFits(size: CGSize) -> CGSize {
var newSize:CGSize = CGSizeMake(self.superview!.frame.size.width, 87)
return newSize
}
}
I don't do swift, but the answer is easy, here's ObjC
- (CGSize)sizeThatFits:(CGSize)size {
return CGSizeMake([self superview].frame.size.width, 40);
}
Here's my interpretation in Swift:
import UIKit
class TallerNaviBar: UINavigationBar {
override func sizeThatFits(size: CGSize) -> CGSize {
var newSize:CGSize = CGSizeMake(superview.width, 87)
return newSize
}
}
The problem you will have isn't with this method, this is the easy part, the problem is forcing the navigation controller to always use this navigation bar
I subclass and resize everything in IOS, including navigation controllers and tabbarcontrollers, in order to enforce that all navigation controllers use this navigation bar, you must subclass a navigationController and only use this navigationcontroller throughout your app, here's how the subclass works, this is Obj C, so you'll have to translate it:
@interface NSHNavigationController () <UINavigationBarDelegate, UINavigationControllerDelegate>
{
}
@implementation NSHNavigationController
#pragma mark Initialization
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self NSHSetupNavigationController];
}
return self;
}
- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass
{
self = [super initWithNavigationBarClass:navigationBarClass toolbarClass:toolbarClass];
if (self) {
[self NSHSetupNavigationController];
}
return self;
}
- (id)initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithRootViewController:rootViewController];
if (self) {
[self NSHSetupNavigationController];
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self NSHSetupNavigationController];
}
return self;
}
- (void)dealloc
{
[self setInternalDelegate:nil];
[self setExternalDelegate:nil];
}
#pragma mark Setup
- (void)NSHSetupNavigationController
{
[self setValue:[[NSHNavigationBar alloc]init] forKeyPath:@"navigationBar"];
}
this is the line that will do it for you:
[self setValue:[[NSHNavigationBar alloc]init] forKeyPath:@"navigationBar"];
Oh yeah, and make sure you are subclassing the nav bar, you said you were, but here's how you do it, it's simple:
#import "NSHNavigationBar.h"
@implementation NSHNavigationBar
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSDictionary *attributes = @{NSForegroundColorAttributeName:[UIColor whiteColor],
NSFontAttributeName:fontMagicForRegularNSHFont};
[self setTitleTextAttributes:attributes];
[self setTranslucent:true];
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (CGSize)sizeThatFits:(CGSize)size {
return CGSizeMake([self superview].frame.size.width, heightResizer(40));
}
- (void)layoutSubviews {
[super layoutSubviews];
}
So, in summary, subclass both the UINavigationBar and the UINavigationController and you are set, this will allow you to manipulate the navigation bar whenever you'd like, you can also type cast your view controller's navigation bars, this is a little nuts and will confuse a lot of people, but here it goes:
-(CustomNavigationBar *)navBar {
return (id)[self.navigationController navigationBar];
}
put the stuff above in your view controller and then you call it like this:
[[self navBar] setBackGroundColor:[UIColor blueColor]];
This will successfully typecast your navigationcontroller to be your custom navigation bar, if you want to change the height of the nav bar from here, then you can do something like this: