In my app, I got a UINavigationController. Unfortunately, when I rotate the device and the interface orientation changes, the UINavigationBar doesn\'t change its height. In
I think this one is kind of similar to you and they have the code snippet:
iPhone: UINavigationBar with buttons - adjust the height
I've done a little testing, and although I don't like the method, it's quite easy to do.
Having looked for a private method that may have worked, I couldn't find one. All I found was:
@property BOOL forceFullHeightInLandscape;
- (BOOL)isMinibar;
There is no setter for -isMinibar
, so we can't set that. I guess that it returns a value based on its height. Also, forceFullHeightInLandscape
was set to NO
, however it still didn't adjust its height.
While changing the autoresizingMask
to include UIViewAutoresizingFlexibleHeight
, the view did resize to be smaller, but now it was too small. However, -isMinibar
suddenly returned YES
. So that made me think of just letting the view resize itself, adjusting it to the right height.
So there we go, a method that works, even without private API calls:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self.navigationBar performSelector:@selector(sizeToFit) withObject:nil afterDelay:(0.5f * duration)];
}
One thing you'll have to deal with is that the views below the bar won't get adjusted to the smaller bar, so that there will be a gap between the bar and the views below. Easiest way to solve this is to add a container view, just like the case with a UINavigationController
. You'd come up with something like:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self performSelector:@selector(resizeViewsForNavigationBar) withObject:nil afterDelay:(0.5f * duration)];
}
- (void)resizeViewsForNavigationBar {
[self.navigationBar sizeToFit];
// Resize containerView accordingly.
CGRect containerViewRect = self.containerView.frame;
containerViewRect.origin.y = CGRectGetMaxY(self.navigationBar.frame);
containerViewRect.size.height = CGRectGetMaxY(self.view.frame) - containerViewRect.origin.y;
self.containerView.frame = containerViewRect;
}
Thanks to Joost I've added
@property BOOL forceFullHeightInLandscape;
to my custom UINavigationBar class. And set in :
-(id)initWithFrame:(CGRect)frame{
forceFullHeightInLandscape = YES;
Worked like a charm
(void)viewWillLayoutSubviews {
self.navigationItem.titleView.bounds = self.navigationController.navigationBar.bounds;
}
Similar to Joost's answer, but putting the method in willAnimateRotationToInterfaceOrientation
has a better animation effect than willRotateToInterfaceOrientation
. (There's no animation delay)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self.navigationBar sizeToFit];
}
I think the behavior you want only happens when a navigation controller ( which represents the bars (navigation or toolbar)), is added to the window in the app delegate or presented by a tab bar, etc.
You can add a navigation bar via IB or code, it doesn't mean you have a navigation controller. My opinion is, create a navigation controller and initialize it with the view controller you're working in. Probably when the view rotates, the nav bar will shrink a little, the way you like.
Hope this helps