iOS 7 | Navigation bar / Toolbar buttons very close to status bar
Asked Answered
U

6

42

I have a problem when dragging a navigation bar or toolbar (storyboard) to my view controller.

UINavigationBar:

UINavigationBar

As you can see in the image above, the right button is almost overlapping the status bar.

With a UIToolbar it happens the same:

UIToolbar

This view controllers are intended to be used as a Modal, that's the reason I'm not using a UINavigationController.

In another section I use a UINavigationController and it appears as I expect:

UINavigationController

How can I drag a UINavigationBar / UIToolbar to a view controller without overlapping the status bar?

Unremitting answered 19/9, 2013 at 17:55 Comment(6)
Can you tell exactly what you did to solve this issue? I tried the comments under the correct answer but they didn't help. I am having the same issue with the uitoolbar that i dragged in the storyboard.Salty
Hi @AJ112. Are you using auto layout? If not, try setting the fixed point of the UIToolbar to the upper left corner. Then, put the code in the comments below (the frame code). It should work.Unremitting
Yes i am using the Autolayout. Toolbar is already set as the fixed point to the upper left corner but it didn't work. Here is my question:#18936321Salty
Just to confirm... Is your toolbar at (0,20)? Have you implemented UIToolbarDelegate on your UIViewController? if so... Have you set the delegate to your IBOutlet UIToolbar in viewDidLoad? You view controller has the implementation of UIToolbarDelegate? (positionForBar:)Unremitting
and this #18737686Adp
As of 2019 you just need to set the top layout constraints to 0 (the top). Otherwise you end up with a nav bar negatively positioned somehow.Photoluminescence
H
48

The navigation bars or toolbars have to be at (0, viewController.topLayoutGuide.length) with bar positioning of UIBarPositionTopAttached. You should set the delegate of your navigation bar or your toolbar to your view controller, and return UIBarPositionTopAttached. If positioned correctly, you will have the result in your third image.

More information here: https://developer.apple.com/documentation/uikit/uibarpositioningdelegate?language=objc

Hydrotherapy answered 19/9, 2013 at 17:59 Comment(6)
Hi! Thank you. I tried what you suggest but it didn't work. This is what I did: .h -> @property (weak, nonatomic) IBOutlet UIToolbar *toolbar; AND UIViewController<UIToolbarDelegate> ||then in .m (viewDidLoad) -> [this.toolbar setDelegate:self]; Then I added to .m -> #pragma mark UIToolbarDelegate - -(UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; } || Am I doing something wrong?Unremitting
You have to position the bar at (0,20), otherwise it would not work. In viewDidLoad: CGRect frame = self.toolbar.frame; frame.origin.y = 20; self.toolbar.frame = frame;. If you target only for iOS6 and iOS7, you can do this 20pt move entirely in Xcode using iOS6/7 deltas.Invitatory
Thank you so much! The problem was that the anchor point of the toolbar was to the left (between the corners) not to the left corner so it wasn't working. (I'm not using auto layout :P). I wonder why the storyboard doesn't put the uinavigationbar or uitoolbar at (0, 20) as a default position. Thanks again!Unremitting
Does the UIBarPositionTopAttached have to be set programmatically, or is there an IB equivalent?Burseraceous
It has to be returned in a delegate method.Invitatory
@Cœur Thank you for taking the time to edit my answers with updated documentation links. Please add links to ObjC documentations for questions where ObjC was expected.Invitatory
D
25

Do these steps

Drag the NavigationBar to your ViewController in Xib, set the ViewController as its delegate. Note that the NavigationBar should be at (0, 20)

In ViewController, conform to the UINavigationBarDelegate

@interface ETPViewController () <UINavigationBarDelegate>

Implement this method

- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar
{
    return UIBarPositionTopAttached;
}

positionForBar tells the NavigationBar if it should extend its background upward the Status Bar

Discriminative answered 24/11, 2013 at 8:26 Comment(2)
Hi, what about when you're using a ToolBar instead of a NavBar? I tried the same procedure and I also replaced <UINavigationBarDelegate> with <UIToolbarDelegate> but it doesn't work.Eat
You should use the UIBarPositioningDelegate insteadRebeccarebecka
A
10

Please see my answer here, I've copied the content below for convenience:

https://mcmap.net/q/226062/-how-to-present-a-view-controller-on-ios7-without-the-status-bar-overlapping

The easiest workaround I've found is to wrap the view controller you want to present inside a navigation controller, and then present that navigation controller.

MyViewController *vc = [MyViewController new];
UINavigationController *nav = [[UINavigationController alloc] 
    initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:NULL];

Advantages:

  • No mucking with frames needed.
  • Same code works on iOS 6 an iOS 7.
  • Less ugly than the other workarounds.

Disadvantages:

  • You'll probably want to leave your XIB empty of navigation bars or toolbars, and programatically add UIBarButtonItems to the navigation bar. Fortunately this is pretty easy.
Anthropogeography answered 20/9, 2013 at 8:50 Comment(0)
M
5

You can resolve this issue by using Auto Layout, as per this techincal note (Preventing the Status Bar from Covering Your Views).

Here are some excerpts:

Add the Vertical Space Constraint to the top-most view

  • Control drag from the UIToolbar to the "Top Layout Guide"
  • In the popover, choose "Vertical Spacing"
  • Change the "Vertical Space Constraint" Constant to 0 (zero)

If you have other subviews below the UIToolbar, anchor those views to the toolbar instead of the Top Layout Guide

This will support ios6 and ios7.

Mesenchyme answered 27/9, 2013 at 2:39 Comment(1)
Just worth mentioning that top and bottom layout guides are only available in storyboards, where views are embedded in view controllers. Using nib files, the process is more complex.Invitatory
T
0

You can also manage it by increasing height of navigation bar by providing image of size 620x128 for ios version. And this image is used in :

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)?YES:NO) {
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"newImage.png"] forBarMetrics:UIBarMetricsDefault];
}else{
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"previousImage.png"] forBarMetrics:UIBarMetricsDefault];
}
Tool answered 27/9, 2013 at 12:35 Comment(0)
O
0

I gave up and had to set the navbar height constraint to 64 in x xib based VC cause viewController.topLayoutGuide.length is 0 in viewDidLoad despite statusbar being present :-[ which means in a non universal app on ipad you'd have 20 px on the top of the view wasted (cause status bar is separate from the iphone simulation window)

Osteopath answered 17/3, 2016 at 16:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.