Position of navigation bar for modal view - iOS7
Solution 1
The best way to overcome this in iOS 7 is by conforming to the new UIBarPositioningDelegate
protocol.
You connect the delegate of your NavigationBar to your view controller (set your view controller as the delegate for the navigation bar either through storyboard or through code) and conform to that protocol and by implementing the method
-(UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }
You can remove the top gap in the view controller. You need to place the bar 20 points below the top edge
Solution 2
Figured out the 3 options for solving this problem.
Option 1: Resize the Nav Bar
float currentVersion = 7.0;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= currentVersion) {
// iOS 7
self.navBar.frame = CGRectMake(self.navBar.frame.origin.x, self.navBar.frame.origin.y, self.navBar.frame.size.width, 64);
}
Option 2: Hide the Status Bar
For example, in the modal view where you want to hide the status bar
Add this method
- (BOOL)prefersStatusBarHidden
{
return YES;
}
In viewDidLoad add
float currentVersion = 7.0;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= currentVersion) {
[self prefersStatusBarHidden];
[self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
}
else {
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
Now, when you dismiss the modal view, and you want your status bar back. Add this in viewWillAppear
float currentVersion = 7.0;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= currentVersion) {
[self prefersStatusBarHidden];
[self performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
NSLog(@"ios7");
}
else {
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
}
and this, but return NO this time
- (BOOL)prefersStatusBarHidden
{
return NO;
}
Option 3: Embed in Nav Controller
Select your modal view, just embed that in a Navigation Controller.
Solution 3
In Swift:
The best way to overcome this in iOS 8.1 and Swift is by conforming to the new UIBarPositioningDelegate protocol.
You connect the delegate of your NavigationBar to your view controller and conform to that protocol and by calling the method:
func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
return UIBarPosition.TopAttached
}
You can remove the top gap in the view controller. You need to place the bar 20 points below the top edge.
Solution 4
For Swift3 use following..
func position(for bar: UIBarPositioning) -> UIBarPosition{
return .topAttached;
}
![DogCoffee](https://i.stack.imgur.com/BbIG3.png?s=256&g=1)
Comments
-
DogCoffee almost 4 years
In a navigation controller, you automatically get the correct colour and position of a navigation bar as expected.
like this
But in modal view, when you drag in a navigation bar, you can position it right at the top, which is too close to the carrier / battery info.
So you can drag it down, guess how far so it matches the position of the automatically created one, but then you have a colour discrepancy. I have tried changing status bar settings in IB, doesnt make a difference.
Is there a correct way to do overcome this, as in make a modal view look like the auto generated nav view.
Thanks
-
Naveed over 10 yearsI was having the same problem and I used Option 1 from your answer It works great. Have you found another way of some how setting the size of the navbar maybe in interface builder? I was just wondering if embedding something in navigation controller automatically generates that bar with the correct then there might be a way of doing it instead of resizing it in each view controller.
-
DogCoffee over 10 years@Naveed, havent found a way in IB. I didn't look at your second idea yet.
-
dulgan over 10 yearsUsing Autolayout isn't the problem at all here. I think people want to use Autolayout AND solve this issue, so sorry for downvote but your answer is not useful
-
dulgan over 10 yearsI think all this is a bit complicated, just give a shot at what I posted below and give me a feedback if you can. Thanks anyway for your workaround ideas
-
Matt over 10 yearsThanks @CharlieSeligman but seeing that my answer isn't very old, people might have seen it enough especially since it has not been marked as the right one.
-
Anton over 10 years@Matt saved me a few grey hairs! Thank's a lot.
-
DogCoffee about 10 years@Matt, good stuff! I changed my answer to yours, this is a clean approach.
-
Matt about 10 years@Smick I'm happy to have helped. It took me a lot of digging when the iOS7 was launched.
-
Joe C about 9 yearsWhat do you mean by "You connect the delegate of your NavigationBar to your view controller"? myNavBar.delegate = self doesn't work if you've only conformed to UIBarPositioningDelegate in your ViewController.
-
Matt about 9 yearsI have done it both ways. Place the navBar in Storyboard 20 points below and control drag the delegate to the view controller itself from within the storyboard. Or, you could make an outlet and do myNavBar.delegate = self from within the view controller and conform to UIBarPositioningDelegate and implement the method. Are you sure your outlet is connected to the property or if it is created by code you have placed it right?
-
sysuser about 9 yearsYour third solution is working out wonders for me. It solved me two problems 1 - not having the title button close to the battery 2 - Title doesn't disappear when I scroll down the table, I need to do more work otherwise for a standalone navigation bar not embedded in a nav controller.
-
kelin almost 9 yearsAssigning to navigationBar.frame has no effect.
-
Sahil Khanna about 8 yearsI tried option 3 and it worked fine. Option 3 seemingly is a clean option as it avoids writing additional code.
-
Jarrod Smith about 8 yearsCan you give an example detailing how to declare and assign the delegate? I'm doing
class ComposeViewController: UIViewController, UIBarPositioningDelegate
and thenself.navigationController?.navigationBar.delegate = self
. This doesn't compile sinceUIBarPositioningDelegate
does not conform toUINavigationBarDelegate
. -
Gary Johnson about 8 yearsThanks so much for this. I used a constraint to lock the top of the nav bar to the top layout guide, instead of 20px from the top-level view. Both seem to work when the status bar gets bigger (CMD+Y in simulator). Any downsides to using the top layout guide instead?
-
Matt about 8 years@GaryJohnson when you add a constraint to the navigation bar placed 20pts below, the constraint you add will be 0pts to top layout guide. It won't be to the superview. So what you did is exactly how you're supposed to do it. As by default on iOS 8 and above the status bar is hidden for landscape phone.
-
rmp over 7 yearsThis worked for me but just to be clear, and answer @Matt, you need both
UINavigationBarDelegate
andUIBarPositioningDelegate
-
Matt over 7 years@rmp That's what I meant by "You connect the delegate of your NavigationBar". The easiest way is through storyboard but you can of course do it in code.