iOS 7 UIToolBar Overriding With Status Bar

14,555

Solution 1

If your setup is a split view like setup with two container views, you should be able to do this. When you set up the container views, drag the top up until you see the dotted blue line that indicates the top is at the bottom of the status bar. Do this with both container views. Add the tool bar to the embedded controller (not the container view), pinned to the top of that controller's view. With the left view being embedded in a navigation controller, my screen looked like this:

enter image description here

Solution 2

_toolBar.delegate = self;

- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar {
    CGRect frame = _toolBar.frame;
    frame.origin = CGPointMake(0, [UIApplication sharedApplication].statusBarFrame.size.height);
    _toolBar.frame = frame;

    return UIBarPositionTopAttached;
}

portrait bar

landscape bar

Solution 3

Your view's top constraint should no longer be top space to superview, but rather top space top top layout guide.

You can do this by moving the top space down beneath the status bar and then using the constraint menu to add the constraint to the nearest neighbor, which should now be the top layout guide, or you can do it as describe in this link on apple's developer library.

Solution 4

Remember that you shouldn't just move things down in IB for two reasons:

  1. Not compatible with iOS 6
  2. Won't extend the top bar background effect under the status bar

What not to do...

So, if you want to iOS6 & iOS7 compatibility, you could add a conditional for objects that require customization in ViewDidLoad. Caveat being this is a last case scenario - always try to remedy it with autolayout / IB first:

#import <Availability.h>

#ifdef __IPHONE_7_0

        CGRect barFrame = topBar.frame;
        barFrame.origin = CGPointMake(0, [UIApplication sharedApplication].statusBarFrame.size.height);
        [topBar setFrame:barFrame];

        // move other stuff around too

    #endif

And set your bar delegate much like Luniz above,override positionForBar to .

topBar.delegate = self;

- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar {

    return UIBarPositionTopAttached;
}

Solution 5

I was trying to do pretty much the same thing, but I didn't like the white status bar of the accepted answer. I managed to make the toolbar placed underneath the status bar so that it has a consistent color to the Navigation Bar that is next to it in the Master view.

My solution was to make the Toolbar 64 points tall and set the Topspace to the superview to 0.

When doing this you have to make sure you are not creating the constraint to the Top Space Layout Guide. I was able to get that done in Interface Builder by setting the Frame to 0,0 with a Height of 64. Then I used the Pin dialog off of the floating tool menu. I used zero with the top I beam to create the constraint.

The bottom edges match in the Master and Detail and the coloring is consistent. The controls in my toolbar ended up uncrowded.

Share:
14,555
AJ112
Author by

AJ112

...

Updated on June 15, 2022

Comments

  • AJ112
    AJ112 almost 2 years

    I have upgraded my project from iOS 6 to iOS 7 but there seems a little problem. The status bar and a tool bar is overriding and very close to each other. The tool bar was earlier added by manually dragging it in the storyboard. This is how its showing up:

    toolbar

    I have seen a few questions that are suggesting to use "positionForBar:" and "- (UIBarPosition)positionForBar:(id)bar" but i don't know exactly how to use them, a little explanation and easy way to do it might help. Thanks!

    UPDATE: Following is some code that also needs a fix. It was working fine earlier but since the detailviewcontroller (WebViewController) is now embeded inside a navigation controller, the below code is causing an exception. Looks like i need to modify the first line in this method.

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
            WebViewController *wvc = [self.navigationController.parentViewController childViewControllers][1];
            RSSItem *entry = [[channel items] objectAtIndex:[indexPath row]];
            wvc.title = entry.title;
            wvc.urlString = entry.link;   
    }
    
  • AJ112
    AJ112 over 10 years
    What if the view is in the container inside a super view. What to do then?
  • Luniz
    Luniz over 10 years
    Your toolBar is inside the container?
  • AJ112
    AJ112 over 10 years
    Toolbar is in the view but that view is inside the container? I used the code in your answer but it didn't work. Any idea what else i should change in order for it to work?
  • Luniz
    Luniz over 10 years
    Maybe your container view's origin.y is negative? Try to move your container view. And check your toolBar's autoresizing mask. It should be UIViewAutoresizingFlexibleTopMargin.
  • Luniz
    Luniz over 10 years
    And use UIViewAutoresizingFlexibleWidth if you need portrait and landscape orientations in your app.
  • AJ112
    AJ112 over 10 years
    Can i use the navigation bar in the detail view container instead of a toolbar. As you know the color we give to navigation bar is applied to the status bar as well in iOS 7 and thats what i am trying to achieve.
  • rdelmar
    rdelmar over 10 years
    @AJ112, Sure. You can embed that controller in a navigation controller, or just drag in a navigation bar.
  • AJ112
    AJ112 over 10 years
    Yes i can either use a nav bar or embed the detailview in a navigation controller. With the toolbar it was working fine, i replaced the toolbar with a navigation bar dragged in the detailview. It works but it collides with the status bar just like the toolbar. If i move the navigation bar in detailview 20 points below manually, still i cannot change the color of status bar by changing the color of the nav bar. Turns out that manually dragged nav bar does not change the status bar color with it.
  • AJ112
    AJ112 over 10 years
    The second option is to embed the detailview in the navigation controller. I tried doing that and its the right thing to do if i want the status bar and navbar color the same for iOS 7. but it throws exception. Here is the link to a sample project with navigation bar added to it jmp.sh/v/cutCPH6EkzQgotOerSLo
  • rdelmar
    rdelmar over 10 years
    @AJ112, I'm not sure under what circumstances you get an exception, but it's probably because you need to change how you define self.splitViewController in the detail controller. Instead of self.splitLikeController = (RDSplitLikeController *)self.parentViewController you need to have self.splitLikeController = (RDSplitLikeController *)self.navigationController.parentViewController. When I embedded the detail controller in a navigation controller, changed what I said above, and added the bar button, everything worked fine.
  • AJ112
    AJ112 over 10 years
    It worked. I was missing this little modification you mentioned. Thanks a lot for the help. I have marked your answer as the correct one. However there is one small problem that i have added in the question as an update, kindly take a look. Thanks
  • rdelmar
    rdelmar over 10 years
    @AJ112, Where you have, WebViewController *wvc = ... change that to UINavigationController *nav ==..., then add another line WebViewController *wvc = nav.topViewController;
  • capikaw
    capikaw over 10 years
    Of course, the whole first part could be solved by simply setting the 'Use Full Screen (Depreciated)' (aka wantsfullscreen) flag in IB.
  • AJ112
    AJ112 over 10 years
    hey mind taking a look into this question stackoverflow.com/questions/19507639/…
  • arlomedia
    arlomedia about 10 years
    Thanks ... adding 20 to the height of the toolbar was the only solution I found that didn't require Autolayout, which requires iOS 6. I have a lot of iPad 1 users, so I want to maintain support for iOS 5 in my app.
  • Jacob Wan
    Jacob Wan about 10 years
    This link was really helpful to me. One thing I had to wrestle with was that XCode kept wanting to create the new vertical spacing constraint by associating the bottom of the UIToolbar with the Top Layout Guide, requiring negative values to make things look right. To fool XCode into associating the top of the UIToolbar with the Top Layout Guide, I first had to move the top of it down below the guide, and then create the constraint. After that, I set the constraint value to zero, which bolted the two together.
  • arlomedia
    arlomedia about 10 years
    Actually when I increased the height of the toolbar, I found that the toolbar title (UIBarItem) remained bottom-aligned but toolbar buttons (UIBarButtonItem) were vertically centered -- their position was too high. The only way I could find to adjust the position was to set up the toolbar button as a UIButton set as the customView of the UIBarButtonItem, then adjust the frame of the UIButton. If you need to apply the toolbar tintColor to the button icon, then you have to use a UIImageView instead of a UIButton.