0
votes

I have a UINavigationController to which I need to add a second UINavigationBar. Neither of those bars is translucent. Problem is, view controllers that I put inside this navigation controller are partially covered by my second navigation bar. Where do I adjust the frames of those view controllers' views so that I don't get a "blinking" effect of them changing frames while being visible?

EDIT: This is in viewDidLoad:

UINavigationBar *secondaryNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, 50)];
secondaryNavBar.translucent = NO;
if ([secondaryNavBar respondsToSelector:@selector(setBarTintColor:)]) { //it has to work on iOS 6 as well
    secondaryNavBar.barTintColor = [UIColor darkGrayColor];
    secondaryNavBar.tintColor = [UIColor whiteColor];
}
else {
    secondaryNavBar.tintColor = [UIColor darkGrayColor];
}
[self.view addSubview:secondaryNavBar];
self.secondaryNavBar = secondaryNavBar;
1
Two navigation bars ? Really a good idea ? - rdurand
I know it sounds pretty bad, but it kinda make sense. In normal navigation bar I have to always show 2 buttons wherever in the app you are, while second bar is not always shown and it's used for some navigation stuff. - johnyu
Do you add the second navigation bar to your navigation controller ? - rdurand
Yes, it is a subview of my UINavigationController's subclass. - johnyu
If you add the nav bar with code, can you post it ? - rdurand

1 Answers

1
votes

Here's a working solution. Certainly not the best, and I did not make it to support iOS 6, you'll have to work on it and test it.

CustomNavigationController.m :

@implementation CustomNavigationController {

    UINavigationBar *bottomNavBar;
}

- (void)viewDidLoad {

    [super viewDidLoad];        
    [self showNavBar];
}

- (void)showNavBar {

    UINavigationBar *secondaryNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, 50)];
    secondaryNavBar.translucent = NO;
    if ([secondaryNavBar respondsToSelector:@selector(setBarTintColor:)]) { //it has to work on iOS 6 as well
        secondaryNavBar.barTintColor = [UIColor darkGrayColor];
        secondaryNavBar.tintColor = [UIColor whiteColor];
    }
    else {
        secondaryNavBar.tintColor = [UIColor darkGrayColor];
    }

    [self.view addSubview:secondaryNavBar];
    bottomNavBar = secondaryNavBar;

    [self layoutNavBar];
}

- (void)layoutNavBar {

    // Get the currently displayed view
    UIView *contentView = self.topViewController.view;
    // Get its frame and height
    CGRect contentFrame = contentView.frame;
    float height = contentFrame.size.height;

    // Adapt height and y origin with the new nav bar
    contentFrame.size.height = height - bottomNavBar.frame.size.height;
    contentFrame.origin.y = bottomNavBar.frame.origin.y + bottomNavBar.frame.size.height;

    // Set the view's frame
    contentView.frame = contentFrame;

}


@end

ViewController.m :

@implementation ViewController

-(void)viewDidAppear:(BOOL)animated {

    CustomNavigationController *navigation = (CustomNavigationController*)self.navigationController;
    [navigation layoutNavBar];
}

@end

Note that you have to call layoutNavBar on viewDidAppear, or the view's frame will be reset by your app. This is not a perfectly clean solution, but a pretty good fix.