18

I have an app that was developed in iOS 6. But now in iOS 7 or even my app compiled for iOS 6, but running on an iOS 7 device the top navigation bar (the new giant one in iOS 7) my content is hidden. The top navigation bar covers it. If I manually move it down with CGRect it looks good in iOS 7, but now iOS 6 looks horrible (to much space above it).

The app was built with autolayout off because autolayout is way to difficult to get things setup correctly.

My question is, is there an easy way to move the content down for iOS 7 only? I really don't want to have to turn autolayout back on and spend a month trying to get all the UI elements back in place. The app is pretty sophisticated with 30+ screens and a lot of animating view on screens.

paulrehkugler
  • 3,241
  • 24
  • 45
jdog
  • 10,351
  • 29
  • 90
  • 165
  • you don't need autolayout to fix it, please read [iOS 7 UI Transition Guide](https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/AppearanceCustomization.html) – HepaKKes Sep 29 '13 at 21:55

4 Answers4

30

I think there's still a little bit of misconception going around this layout problem even if iOS 7 was rolled out more than a year ago. So I eventually decided to elaborate further my answer.

Here's the thing.

Because automaticallyAdjustsScrollViewInsets' default value is YES, a pretty straightforward solution could be adding the following code:

if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) { // if iOS 7
    self.edgesForExtendedLayout = UIRectEdgeNone; //layout adjustements
}

into the ViewController's -viewDidLoad method.

If you wish to remove the status bar quirk (due to the bar translucency, so it's not weird whatsoever) add self.navigationController.navigationBar.translucent = NO. The default value is YES. Note: this has nothing to do with the content, it's related to the content because of translucency but that's an altogether different story!

Because extendedLayoutIncludesOpaqueBars is NO by default, self.navigationController.navigationBar.translucent = NO means basically having

self.edgesForExtendedLayout = UIRectEdgeLeft | UIRectEdgeRight| UIRectEdgeBottom; 

Or, more generally, something like that (it's like pseudocode to give an idea...)

BOOL enableTopEdge =  extendedLayoutIncludesOpaqueBars && !navigationBarIsTranslucent
self.edgesForExtendedLayout = (enableTopEdge & UIRectEdgeTop) | UIRectEdgeLeft | UIRectEdgeRight | UIRectEdgeBottom; 
HepaKKes
  • 1,555
  • 13
  • 22
  • Why do I get "Use of undeclared identifier 'UIRectEdgeNone'" when I use this with the latest version of xcode? No one else seems to mention this issue when I see this answer. – James Oct 30 '13 at 13:37
  • @James because you don't have the iOS 7 SDK. You need to upgrade your XCode to develop for iOS 7. – Pwner Nov 14 '13 at 00:47
  • @Pwner I have upgraded it though. That's why I'm so confused. I downloaded and installed it earlier that day. And it was set to use IOS7 as my base SDK. – James Nov 14 '13 at 14:25
  • When I do this I get an odd effect where the background of the status and navigation bar turns from white, to dark grey to light grey. Is this a common problem? Does anyone know how to stop it from happening? – ThomasW Jan 10 '14 at 06:38
  • @ThomasW you need to set the status bar translucency to `NO` – HepaKKes Aug 12 '14 at 01:26
  • Thanks for great answer! This problem still happens. One question - do you have a link for description of this problem - like why it happens, what is the reasons of this trouble- thanks in advance – Karaban Mar 28 '18 at 12:04
10

You can also try setting the navigationBar.translucent = NO, as was mentioned in this answer.

Community
  • 1
  • 1
paulrehkugler
  • 3,241
  • 24
  • 45
  • 1
    @HepaKKes I don't understand the downvote. If you set the translucency to no, and have "Extend Edges Under Opaque Bars" unchecked in the navigation controller in the storyboard, this is a valid answer. See: http://stackoverflow.com/a/18775241/953105 – paulrehkugler Sep 30 '13 at 15:03
  • I'm still compiling for SDK 6.1, and setting edgesForExtendedLayout had no effect for me, but setting the navigation bar translucency solved the problem. – arlomedia Nov 01 '13 at 22:21
5

To hide the navigation bar, add the following to your UIViewController:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Hide the top navigation bar.
    [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    self.navigationController.navigationBar.shadowImage = [UIImage new];
    self.navigationController.navigationBar.translucent = YES;
}

To show the navigation bar, use the following:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Show the top navigation bar.
    self.navigationController.navigationBar.translucent = NO;
}

Below are the results on iOS7:

Navigation bar is hidden. Navigation bar is shown.

The screenshot on the left is with navigation bar hidden, while the image on the right is with navigation bar displayed - the contents of the table are correctly hidden under the navigation bar.

Hope this helps!

Zorayr
  • 23,770
  • 8
  • 136
  • 129
  • thanks for the code, one thing i noticed is that you can't click on anything since the nav bar is technically invisible (but not removed) – kevinl Jan 21 '14 at 23:07
1

Put self.edgesForExtendedLayout = UIRectEdgeNone;

in your ViewDidLoad method

Cris
  • 464
  • 1
  • 3
  • 15