Uiview on top navigation bar over scale site stackoverflow.com

I recently downloaded Xcode 5 DP to test my apps in iOS 7. The first thing I noticed and confirmed is that my view's bounds is not always resized to account for the status bar and navigation bar.

In

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

5, I print the view's bounds:

{{0, 0}, {320, 568}}

This results in my content appearing below the navigation bar and status bar.

I know I could account for the height myself by getting the main screen's height, subtracting the status bar's height and navigation bar's height, but that seems like unnecessary extra work.

How can I fix this issue?

Update:

I've found a solution for this specific problem. Set the navigation bar's translucent property to NO:

self.navigationController.navigationBar.translucent = NO;

This will fix the view from being framed underneath the navigation bar and status bar.

However, I have not found a fix for the case when you want the navigation bar to be translucent. For instance, viewing a photo full screen, I wish to have the navigation bar translucent, and the view to be framed underneath it. That works, but when I toggle showing/hiding the navigation bar, I've experienced even stranger results. The first subview [a UIScrollView] gets its bounds y origin changed every time.

asked Jun 12, 2013 at 20:06

8

You can achieve this by implementing a new property called

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

6 in iOS7 SDK. Please add the following code to achieve this,

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

You need to add the above in your

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

7 method.

iOS 7 brings several changes to how you layout and customize the appearance of your UI. The changes in view-controller layout, tint color, and font affect all the UIKit objects in your app. In addition, enhancements to gesture recognizer APIs give you finer grained control over gesture interactions.

Using View Controllers

In iOS 7, view controllers use full-screen layout. At the same time, iOS 7 gives you more granular control over the way a view controller lays out its views. In particular, the concept of full-screen layout has been refined to let a view controller specify the layout of each edge of its view.

The

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]] self.edgesForExtendedLayout = UIRectEdgeNone;

8 view controller property is deprecated in iOS 7. If you currently specify

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]] self.edgesForExtendedLayout = UIRectEdgeNone;

9, the view controller may display its content at an unexpected screen location when it runs in iOS 7.

To adjust how a view controller lays out its views,

[self setEdgesForExtendedLayout:UIRectEdgeNone];

0 provides the following properties:

edgesForExtendedLayout

The

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]] self.edgesForExtendedLayout = UIRectEdgeNone;

6 property uses the

[self setEdgesForExtendedLayout:UIRectEdgeNone];

2 type, which specifies each of a rectangle’s four edges, in addition to specifying none and all. Use

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]] self.edgesForExtendedLayout = UIRectEdgeNone;

6 to specify which edges of a view should be extended, regardless of bar translucency. By default, the value of this property is

[self setEdgesForExtendedLayout:UIRectEdgeNone];

4.

extendedLayoutIncludesOpaqueBars

If your design uses opaque bars, refine

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]] self.edgesForExtendedLayout = UIRectEdgeNone;

6 by also setting the

[self setEdgesForExtendedLayout:UIRectEdgeNone];

6 property to NO. [The default value of

[self setEdgesForExtendedLayout:UIRectEdgeNone];

6 is NO.]

automaticallyAdjustsScrollViewInsets

If you don’t want a scroll view’s content insets to be automatically adjusted, set

[self setEdgesForExtendedLayout:UIRectEdgeNone];

8 to NO. [The default value of

[self setEdgesForExtendedLayout:UIRectEdgeNone];

8 is YES.]

topLayoutGuide, bottomLayoutGuide

The

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

0 and

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

1 properties indicate the location of the top or bottom bar edges in a view controller’s view. If bars should overlap the top or bottom of a view, you can use Interface Builder to position the view relative to the bar by creating constraints to the bottom of

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

0 or to the top of bottomLayoutGuide. [If no bars should overlap the view, the bottom of

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

0 is the same as the top of the view and the top of

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }
1 is the same as the bottom of the view.] Both properties are lazily created when requested.

Please refer,

H6_

31.8k12 gold badges81 silver badges84 bronze badges

answered Sep 13, 2013 at 11:52

NandhaNandha

6,7562 gold badges23 silver badges33 bronze badges

14

You don't have to calculate how far to shift everything down, there's a build in property for this. In Interface Builder, highlight your view controller, and then navigate to the attributes inspector. Here you'll see some check boxes next to the words "Extend Edges". As you can see, in the first screenshot, the default selection is for content to appear under top and bottom bars, but not under opaque bars, which is why setting the bar style to not translucent worked for you.

As you can somewhat see in the first screenshot, there are two UI elements hiding below the navigation bar. [I've enabled wireframes in IB to illustrate this] These elements, a UIButton and a UISegmentedControl both have their "y" origin set to zero, and the view controller is set to allow content below the top bar.

This second screenshot shows what happens when you deselect the "Under Top Bars" check box. As you can see, the view controllers view has been shifted down appropriately for its y origin to be right underneath the navigation bar.

This can also be accomplished programmatically through the usage of

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

5. Here's a link to the class reference for , and for

[self setEdgesForExtendedLayout:UIRectEdgeNone];

answered Sep 13, 2013 at 11:56

Mick MacCallumMick MacCallum

129k40 gold badges280 silver badges281 bronze badges

4

I created my view programmatically and this ended up working for me:

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

Source [in topLayoutGuide section at bottom of pg.39].

answered Sep 24, 2013 at 8:35

StunnerStunner

12k13 gold badges86 silver badges145 bronze badges

12

Swift 3 / Swift 4 solution that also works with NIBs/XIB files in iOS 10+:

override func viewDidLoad[] {
    super.viewDidLoad[]
    edgesForExtendedLayout = []
}

answered Sep 1, 2016 at 20:17

flo_23flo_23

1,9342 gold badges14 silver badges13 bronze badges

3

If you want the view to have the translucent nav bar [which is kind of nice] you have to setup a contentInset or similar.

Here is how I do it:

// Check if we are running on ios7
if[[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7] {
      CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame];
      float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height;
      myContentView.contentInset = UIEdgeInsetsMake[heightPadding, 0.0, 0.0, 0.0];
}

answered Sep 13, 2013 at 9:16

MagnusMagnus

2,03524 silver badges32 bronze badges

7

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

6 does the trick for iOS 7. However, if you build the app across iOS 7 SDK and deploy it in iOS 6, the navigation bar appears translucent and the views go beneath it. So, to fix it for both iOS 7 as well as for iOS 6 do this:

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific

answered Sep 21, 2013 at 5:18

Raj Pawan GumdalRaj Pawan Gumdal

7,41010 gold badges60 silver badges92 bronze badges

In your apps plist file add a row, call it "View controller-based status bar appearance" and set it to NO.

answered Sep 19, 2013 at 13:45

IdanIdan

9,89010 gold badges49 silver badges76 bronze badges

0

The simplest trick is to open the NIB file and do these two simple steps:

  1. Just toggle that and set it to the one you prefer:

  1. Select those UIView's/UIIMageView's/... that you want to be moved down. In my case only the logo was overlapped an I've set the delta to +15; [OR -15 if you chose iOS 7 in step 1]

And the result:

answered Sep 20, 2013 at 10:27

RiskovRiskov

8427 silver badges12 bronze badges

2

Swift Solution:

override func viewWillAppear[animated: Bool] {
    super.viewWillAppear[animated]
    self.edgesForExtendedLayout = UIRectEdge.None
}

answered Jul 21, 2015 at 17:06

fatihyildizhanfatihyildizhan

8,7147 gold badges64 silver badges88 bronze badges

2

I would like to expand on Stunner's answer, and add an

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

7 statement to check if it is iOS-7, because when I tested it on iOS 6 my app would crash.

The addition would be adding:

if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0]

So I would suggest adding this method to your

  • [void] viewDidLayoutSubviews { // only works for iOS 7+ if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; // snaps the view under the status bar [iOS 6 style] viewBounds.origin.y = topBarOffset -1; // shrink the bounds of your view to compensate for the offset viewBounds.size.height = viewBounds.size.height + [topBarOffset -1]; self.view.bounds = viewBounds; } }

8 file:

  • [void] viewDidLayoutSubviews { if [[[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0] { CGRect viewBounds = self.view.bounds; CGFloat topBarOffset = self.topLayoutGuide.length; viewBounds.origin.y = topBarOffset * -1; self.view.bounds = viewBounds; } }

answered Oct 1, 2013 at 15:36

werdsackjonwerdsackjon

3944 silver badges11 bronze badges

Swift 3

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

0

answered Jul 4, 2017 at 7:27

ShahrukhShahrukh

7407 silver badges25 bronze badges

I have a scenario where I use the BannerViewController written by Apple to display my ads and a ScrollViewController embedded in the BannerViewController.

To prevent the navigation bar from hiding my content, I had to make two changes.

  1. Modify BannerViewController.m

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

1

  1. Modify my ScrollViewContoller

if [[self respondsToSelector:@selector[edgesForExtendedLayout]]]
        self.edgesForExtendedLayout = UIRectEdgeNone;

2

Now the ads show up correctly at the bottom of the view instead of being covered by the Navigation bar and the content on the top is not cut off.

How do I show a view over tabbar in Swift?

First create create separate swift file and name it MainTabbedView. In this view create the tabbar by using the following code. Create the tabbar and also create five simple views like HomeView, SearchView, SessionsView, ChatView & ProfileView which will be attached with the tabbar bar as you can see in the code above.

How do I hide the top navigation bar in Swiftui?

Hide a navigation bar with navigationBarHidden[true]. . navigationBarHidden will only affect the current view. If you push a new view to a navigation stack with a NavigationLink , the navigation bar will reappear on the pushed view.

What is the height of navigation bar iPhone?

Navigation Bar:.

Chủ Đề