Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Status bar sized incorrectly with a contained UINavigationController

I make a UINavigationController a child of another view controller through containment. Everything works fine, except for a strange issue that occurs when launching the app with the in-call status bar turned ON and then switching it back OFF after the app UI is on the screen. There appears a strange black gap in place of the status bar.

Consider the self-contained example app below:

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opt
{
  // Content
  UILabel * aLbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 200, 40)];
  aLbl.text = @"In-call status bar issue";

  UIViewController * aContent = [[UIViewController alloc] init];
  aContent.title = @"Title";
  aContent.view.backgroundColor = UIColor.whiteColor;
  [aContent.view addSubview:aLbl];

  UINavigationController * aNav = [[UINavigationController alloc]
    initWithRootViewController:aContent];

  // Parentmost view controller containing the navigation view controller
  UIViewController * aParent = [[UIViewController alloc] init];
  [aParent.view addSubview:aNav.view];
  [aParent addChildViewController:aNav];
  [aNav didMoveToParentViewController:aParent];

  self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
  self.window.rootViewController = aParent;
  [self.window makeKeyAndVisible];

  return YES;
}
@end

int main(int argc, char ** argv)
  { @autoreleasepool { return UIApplicationMain(argc, argv, nil, @"AppDelegate"); } }

The easiest way to reproduce the problem is:

  1. Start the iOS Simulator.
  2. Press ⌘+Y to turn on the in-call status bar. The status bar will become wide and green.
  3. Launch the app manually and wait for the Navigation Controller to appear.
  4. Press ⌘+Y again to turn off the in-call status bar.

The UI should now look as follows: Black gap instead of the status bar when switching the in-call status bar back off

Anyone know how to fix the problem?

like image 485
Kerido Avatar asked May 19 '15 15:05

Kerido


1 Answers

You are adding a view (the navigation controller's view) as subview to another view (the parent view controller's view), without giving it a frame! This is something you should never do.

Just add these lines to your code:

aNav.view.frame = aParent.view.bounds;
aNav.view.autoresizingMask = 
    UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

Now the navigation controller's view has a frame, and maintains it in relation to its superview.

like image 83
matt Avatar answered Sep 30 '22 18:09

matt