Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto Layout and in-call status bar

I'd like to ask about Auto Layout and in-call status bar. Here's a simple scenario that demonstrates my problem:

  1. Create project with "Use Storyboards" enabled
  2. Add "View Controller" and enable its "Is Initial View Controller"
  3. Set background color of controller's view to red
  4. Add "Table View" into controller's view

The table view should have 4 layout constraints (leading, top, trailing, bottom) to Superview with constant set to 0.

Now when I run this app in Simulator and press + T I can see red background while the in-call status bar animates in. Is it possible to get rid of this glitch?

like image 975
Rudolf Adamkovič Avatar asked May 08 '13 11:05

Rudolf Adamkovič


3 Answers

(Using answer instead of comment due to lack of reputation, sorry.)

I ran into this issue as well and was trying out e.g. the solution pointed out above: It didn't work for me.

So I created a repository with example code to expose the original poster's problem. There are example applications for these scenarios:

  1. the Custom View Controller is the window's root view controller,
  2. the Custom View Controller is a child of a UINavigationController which is the window's root view controller,
  3. the Custom View Controller is a child of a UITabBarController which is the window's root view controller and
  4. the Custom View Controller is a child of a UINavigationController which is as child of a UITabBarController which is the window's root view controller.

It turned out that the solution from CEarwood actually works… when the custom view controller is a child of a UINavigationController (cases 2 and 4). Hoewever, it does not work in cases 1 and 3.

I hope this information is useful.

like image 71
herzi Avatar answered Nov 09 '22 17:11

herzi


For a purely Auto Layout answer you can get a reference to the bottom constraint and adjust its constant when UIApplicationWillChangeStatusBarFrameNotification is received and back to 0 when the DidChange notification is received. Here's the test VC I used:

@interface CEViewController ()

@property (nonatomic, strong) IBOutlet NSLayoutConstraint *bottomConstraint;

@end

@implementation CEViewController

- (void)viewDidLoad {
    [super viewDidLoad];        

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameWillChange:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameDidChange:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
}

- (void)statusBarFrameWillChange:(NSNotification *)note {
    NSValue *newFrameValue = [note userInfo][UIApplicationStatusBarFrameUserInfoKey];

    self.bottomConstraint.constant = newFrameValue.CGRectValue.size.height;
    [self.view setNeedsLayout];
}

- (void)statusBarFrameDidChange:(NSNotification *)note {
    self.bottomConstraint.constant = 0;
    [self.view setNeedsLayout];
}

@end
like image 7
CEarwood Avatar answered Nov 09 '22 18:11

CEarwood


This is an effect from the screen resizing.

When the in-call status bar appears, the view resizes to the size it should have with the in-call status bar active and then moves down as the status bar changes size.

For a brief moment, the view under the table view is visible. What you could do is add a view under the table view extending downwards out of the screen to cover-up the background color.

Another approach is with your AppDelegate, implement:

-application:willChangeStatusBarFrame:

and resize the table view to cover the bit that gets exposed. Then when -application:didChangeStatusBarFrame: gets called, resize it back to the original size.

like image 2
Marcel Avatar answered Nov 09 '22 16:11

Marcel