Search code examples
ioslayoutstatusbar

View changes its own frame when status bar gets hidden or shown


I need to hide and show the status bar in my application, but when I do this with setStatusBarHidden, my navigation bar changes it's own frame (it moves up with 20pt). The content view changes it's own frame accordingly (it moves up with 20pt and increases own height). How can I change this behaviour and let my bar and content stay still while the status bar gets shown or hidden?

I've tried to observe statusBarHidden and forced change the frame of the nav bar and the content view, but I think this is not the best way for UI scaleability. Maybe there is a better way?

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"statusBarHidden"]){
        if ([change[NSKeyValueChangeNewKey]  isEqual: @(1)]){
            self.navigationBar.frame = ({CGRect newFrame = self.navigationBar.frame; newFrame.origin.y = 20; newFrame;});
        }else {
            self.navigationBar.frame = ({CGRect newFrame = self.navigationBar.frame; newFrame.origin.y = 20; newFrame;});
        }
    }
}

UPD

tried to use these settings in my content view controller:

self.edgesForExtendedLayout = UIRectEdgeNone;

...

-(BOOL)automaticallyAdjustsScrollViewInsets{
    return NO;
}
-(BOOL)prefersStatusBarHidden{
    return NO;
}
-(CGSize)preferredContentSize {
    return CGSizeMake(320, 504);
}

doesn't helps at all


Solution

  • Looks like I've found the best solution. I will not hide the status bar with setStatusBarHidden I will overlap it with new opaque window instead:

    overlayWin = [[UIWindow alloc] init];
    overlayWin.backgroundColor = NAVBAR_COLOR;
    overlayWin.windowLevel = UIWindowLevelStatusBar+1.f;
    overlayWin.frame = [UIApplication sharedApplication].statusBarFrame;
    overlayWin.userInteractionEnabled = NO;
    

    No unwanted side effects with other view's layouts. Nice!