114
CGRect cgRect1 = [[UIScreen mainScreen] applicationFrame];


UISearchBar  *mySearchBar = [[UISearchBar alloc] 
               initWithFrame:CGRectMake(0, 0, cgRect.size.width, 40)];

mySearchBar.autoresizingMask = 
              UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight ;


UITableView  *myTableView = [[UITableView alloc] 
     initWithFrame:CGRectMake(0, 40, cgRect.size.width, cgRect.size.height-40)];

myTableView.autoresizingMask = 
               UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;


[self.view addSubview:mySearchBar];
[self.view addSubview:myTableView];

In the earlier versions it is working correctly. The search bar is appearing below the statusbar and navigation bar. The tableview is appearing below the search bar

But when I run this on Xcode 5 sdk iOS 7, the search bar is not visible (I think its placed under the status bar and navigation bar) , and also the navigation bar is appearing over the table view.

Will it be fixed with iOS 7 stable release ?

Or is it the problem of my coding ?

Or should we handle it by adding the y (y = statubar height + nav bar height) value for iOS 7 ?

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 viewDidLayoutSubviews, 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.

Has anyone else experienced 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.

  • 4
    Beta software. Apple developer forums are more appropiate. Also, the problem is explicitely mentioned in the transition guide. – Sulthan Aug 14 '13 at 12:34

9 Answers9

189

That’s not entirely true. There has been a new property introduced in iOS 7 that lets you adjust the layout behavior as in previous versions of iOS. Place this piece of code in your view controller, and you should be good to go! The space your navigation bar takes up should be accounted for automatically

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

You need add the above in your -(void)viewDidLoad method.

Note: You should be using the latest GM release of iOS 7 and Xcode 5 now since the API has changed from beta versions.

One Man Crew
  • 9,420
  • 2
  • 42
  • 51
  • in My code it says edgesForExtendedLayout. Use of undeclared identifier UIExtendedEdgeNone. Please help. –  Aug 12 '13 at 10:59
  • 6
    It's changed to UIRectEdgeNone – Simon Aug 14 '13 at 12:38
  • 6
    That's exactly the reason why such a question shouldn't be asked or answered here. – Sulthan Aug 14 '13 at 12:53
  • Read the question , it's for iOS iOS7 – One Man Crew Sep 11 '13 at 04:43
  • I don't undestand why if you want to keep compatibility with ios6 you are forced to introduce a conditional case by code to check if the controller has that property or not.. – jerrygdm Aug 27 '13 at 08:24
  • if you don't check, u'll end up with an exception – Sathe_Nagaraja Aug 27 '13 at 10:46
  • 12
    This only seems to work if the view's embedded in a UINavigationController. – pojo Sep 16 '13 at 13:34
  • @pojo Does it only work if the app uses UINavigationController? – KarenAnne Sep 26 '13 at 09:30
  • Yah, I saw in this answer that [edgesForExtendedLayout](http://stackoverflow.com/a/18775241/1635363) only works when it is a Container View Controller. – KarenAnne Sep 26 '13 at 09:52
  • it's working very well. because sometimes my object position is going onether position . when ı add to viewdidload , it's solved – Erhan Demirci Oct 09 '13 at 13:28
  • @OneManCrew yes its working fine for me. but my app have Tabbacontroller alos. Rest of the viewcontroller is working fine. Issue in Tabbar view controller. suppose i have 5 tab. 1. when i click on tab (List screen open) it working fine when i click on list detail open fine. up to yet its working fine 2. when i click on tab 2 (another list) open. that time when i clickon tab1 than detail screen main view frame decrease to 64px. i have tried to forcefully increase but not working .. what can i do in this case ?? – Hitarth Jan 24 '14 at 09:31
  • What if the view is not embedded in a UINavigationController,and storyboard or xib etc are not used, then what is the solution? – piaChai Feb 24 '14 at 02:44
  • Does changing the title bar to not be translucent affect this behaviour? – Johnus Mar 07 '14 at 03:57
38

Screenshot from storyboard

If you are working in Storyboard (which I strongly recommend!) this is the solution: You can disable "Extend Edges" of your ViewController in storyboard. You have to do this for each viewController. You can disable extended edges by clicking the viewController icon in stortyboard (besides the productOwner beneath the view itself) and then selecting the attributes inspector (Like the images shows).

This will also set the alignment lines like iOS 6.

Another great tool in xCode 5 is "Preview": click on the butler Button (assistant editor) and select Preview. there you can select iOS 6 and see how your storyboard design will look like on iOS 6.

Its just great:D

[Update]

Be careful: disabling "Extend Edges" might result in a black glow on the navigation bar when the app enters background on iOS7. the glow will also be visible on the multitasking view (double press on home button). this can be solved by setting the background color of the navigation's bar view to white.

[self.navigationController.view setBackgroundColor:[UIColor whiteColor]];
Benjamin Toueg
  • 10,511
  • 7
  • 48
  • 79
MQoder
  • 712
  • 8
  • 21
12

As the OP says, there is a simple solution to this which is to set the navigation bar to be opaque. Rather than doing this in code, simply untick "Translucent" for your root navigation bar:

enter image description here

Bids
  • 2,422
  • 18
  • 26
8

self.edgesForExtendedLayout=UIRectEdgeNone;

It works on iOS 7 simulator(Xcode 5 DP5)

yhlin
  • 189
  • 2
  • 9
  • 2
    this works fine in ios7 but if i ran the app on ios 6 and earlier again the views are moved up. Any solution for this?. Also we need to set this property in each view controller viewdid load method? – loganathan Sep 05 '13 at 19:20
  • you can always check if the current iOS is 7 with this if: `if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)` – Aviel Gross Oct 14 '13 at 08:40
2

these answers were all helpful, especially MQoder's, but for me i also had to set the default top bar to "opaque black navigation".

enter image description here

codercat
  • 22,873
  • 9
  • 61
  • 85
jasonpurdy
  • 151
  • 2
  • 6
1

@One Man Crew's answer is correct, but:

I would recommend to use this code to avoid errors when running the app on older versions :

 #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
     if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;
 #endif
Yossi
  • 2,525
  • 2
  • 21
  • 24
0

self.edgesForExtendedLayout = UIRectEdgeNone;

And you need to do this on AppDelegate#application:didFinishLaunchingWithOptions:

self.window.backgroundColor = [UIColor whiteColor];

Otherwise Navigation Bar's background color will changed to gray. Because the transparent Navigation Bar overlaps window.

Robasan
  • 155
  • 10
0

If you want to keep the transparency when the user scrolls your table view, you can set the contentInset of it:

CGFloat topLayoutGuide = self.topLayoutGuide.length + self.tabBarController.navigationController.navigationBar.frame.size.height;
self.tableView.contentInset = UIEdgeInsetsMake(topLayoutGuide, 0, 0, 0);
Enrico Susatyo
  • 19,372
  • 18
  • 95
  • 156
-1

One solution is to use Navigation Controller. This automatically solve the issue. Also use Xcode 5 instead of Xcode Preview versions since they are beta ones.

Jayprakash Dubey
  • 35,723
  • 18
  • 170
  • 177