Hiding status bar after view has loaded leaves black bar
ios, iphone, objective-c
Solution
Hard-coding any number is always counter to future proofing. Your concerns are correct. There is a bit of a trick to properly handling the hiding of the statusBar. But all the needed information is available.
For example the `UIApplication` singleton has a property named `statusBarFrame` which is precisely what it sounds like, a `CGRect` of the `statusBar`'s frame. The cool thing is that once you have called `setStatusBarHidden:withAnimation:` that property will give you the new frame, even before the animation completes. So really you are simply left with some basic math to adjust the `view`'s `frame`.
In short your gut feeling is correct; always compute things live.
I've had good success with a category method like this. (Even when toggling in-call status bar in simulator(Command - T)):
@implementation UIApplication (nj_SmartStatusBar)
// Always designate your custom methods by prefix.
-(void)nj_setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation{
UIWindow *window = [self.windows objectAtIndex:0];
UIViewController *rootViewController = window.rootViewController;
UIView *view = rootViewController.view;
// slight optimization to avoid unnecassary calls.
BOOL isHiddenNow = self.statusBarHidden;
if (hidden == isHiddenNow) return;
// Hide/Unhide the status bar
[self setStatusBarHidden:hidden withAnimation:animation];
// Get statusBar's frame
CGRect statusBarFrame = self.statusBarFrame;
// Establish a baseline frame.
CGRect newViewFrame = window.bounds;
// Check if statusBar's frame is worth dodging.
if (!CGRectEqualToRect(statusBarFrame, CGRectZero)){
UIInterfaceOrientation currentOrientation = rootViewController.interfaceOrientation;
if (UIInterfaceOrientationIsPortrait(currentOrientation)){
// If portrait we need to shrink height
newViewFrame.size.height -= statusBarFrame.size.height;
if (currentOrientation == UIInterfaceOrientationPortrait){
// If not upside-down move down the origin.
newViewFrame.origin.y += statusBarFrame.size.height;
}
} else { // Is landscape / Slightly trickier.
// For portrait we shink width (for status bar on side of window)
newViewFrame.size.width -= statusBarFrame.size.width;
if (currentOrientation == UIInterfaceOrientationLandscapeLeft){
// If the status bar is on the left side of the window we move the origin over.
newViewFrame.origin.x += statusBarFrame.size.width;
}
}
}
// Animate... Play with duration later...
[UIView animateWithDuration:0.35 animations:^{
view.frame = newViewFrame;
}];
}
@end
Problem
I'm running into a bit of a weird problem when hiding the status bar after the view had loaded. If I add the following method in the ViewDidLoad method, the status bar is completely removed from the view: ``` [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; ``` However, if I call this method in an IBAction or another method, the status bar still slides away but leaves a black bar the same height as itself behind. I've thought about shifting the entire view up by 20px but is this really a fix? I don't want to just overlap a black bar incase the status bar height changes in future OS upgrades.