在iOS上隐藏状态栏的正确方法,包括动画和调整根视图的大小

hpi*_*que 33 iphone statusbar uiviewcontroller ios uistatusbar

考虑一个视图控制器,当单击按钮时需要滑出(或隐藏)状态栏.

- (void) buttonClick:(id)sender
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES
                                            withAnimation:UIStatusBarAnimationSlide];
}
Run Code Online (Sandbox Code Playgroud)

上面有效地隐藏了状态栏,但没有适当调整根视图的大小,在顶部留下20像素的间隙.

我期望的是根视图扩展到以前状态栏使用的空间(动画,持续时间与状态栏动画相同).

这样做的正确方法是什么?

(我知道有很多类似的问题,但我找不到任何关于按需隐藏状态栏而不是隐藏它以显示新的视图控制器)

"蛮力"的做法

显然,以下作品......

[[UIApplication sharedApplication] setStatusBarHidden:YES
                                        withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.25 animations:^{
    CGRect frame = self.view.frame;
    frame.origin.y -= 20;
    frame.size.height += 20;
    self.view.frame = frame;
}];
Run Code Online (Sandbox Code Playgroud)

......但有缺点:

  • 硬编码幻灯片动画的持续时间
  • 硬编码状态栏的高度
  • 根视图原点保持在(0,-20).我喜欢我的框架尽可能从(0,0)开始.

我已经尝试过了什么

  • 确保根视图的autoresize掩码具有UIViewAutoresizingFlexibleTopMarginUIViewAutoresizingFlexibleHeight.
  • [self.view setNeedsLayout]隐藏状态栏后调用.
  • [self.view setNeedsDisplay]隐藏状态栏后调用.
  • 设置wantsFullScreenLayoutYES隐藏状态栏之前和之后.

awf*_*ode 25

对于那些尝试使用基于视图控制器的状态栏外观实现此功能的用户,需要在视图控制器中实现prefersStatusBarHidden方法

 - (BOOL)prefersStatusBarHidden
{
    // If self.statusBarHidden is TRUE, return YES. If FALSE, return NO.
    return (self.statusBarHidden) ? YES : NO;
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的按钮单击方法中:

- (void) buttonClick:(id)sender
{
    // Switch BOOL value
    self.statusBarHidden = (self.statusBarHidden) ? NO : YES;

    // Update the status bar
    [UIView animateWithDuration:0.25 animations:^{
        [self setNeedsStatusBarAppearanceUpdate];
    }];
}
Run Code Online (Sandbox Code Playgroud)

要设置动画样式,请使用以下命令:

-(UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
    return UIStatusBarAnimationSlide;
}
Run Code Online (Sandbox Code Playgroud)

并定制风格:

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}
Run Code Online (Sandbox Code Playgroud)


Lef*_*ris 15

这工作正常,没有任何硬编码.

CGRect appFrame = [[UIScreen mainScreen] applicationFrame];

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.25 animations:^{
    self.navigationController.navigationBar.frame = self.navigationController.navigationBar.bounds;
    self.view.window.frame = CGRectMake(0, 0, appFrame.size.width, appFrame.size.height);
}];
Run Code Online (Sandbox Code Playgroud)

  • AFAIK,没有办法获得状态栏动画持续时间.您可以通过订阅键盘willshow/willhide通知来获取键盘动画持续时间,但不能用于UIStatusBar.iOS中也似乎存在一个错误,因为从未修复过的年龄,并且在隐藏或显示状态栏时不会触发UIApplicationDidChangeStatusBarFrameNotification/UIApplicationWillChangeStatusBarFrameNotification ... (3认同)

小智 8

您可以显示然后关闭模态视图控制器以正确隐藏状态栏

- (void)toggleStatusBar {
    BOOL isStatusBarHidden = [[UIApplication sharedApplication] isStatusBarHidden];
    [[UIApplication sharedApplication] setStatusBarHidden:!isStatusBarHidden];

    UIViewController *vc = [[UIViewController alloc] init];
    [self presentViewController:vc animated:NO completion:nil];
    [self dismissViewControllerAnimated:NO completion:nil];
    [vc release];
}
Run Code Online (Sandbox Code Playgroud)

我在"willAnimateRotationToInterfaceOrientation"方法中使用此代码进行横向定位,一切正常.但我不知道它是否适用于动画.


Sha*_*med 7

隐藏或显示也会重新调整视图大小的状态栏:

-(void)statusBar:(BOOL)status {
UIViewController *rootViewController = self.view.window.rootViewController;
UIView *view = rootViewController.view;

// Hide/Unhide the status bar
[[UIApplication sharedApplication] setStatusBarHidden:status]; // BOOL : YES or NO

// statusBar frame
CGRect statusBarFrame = [UIApplication.sharedApplication statusBarFrame];
// Establish baseline frame
CGRect newViewFrame = self.view.window.bounds;

// Check statusBar frame is worth dodging
if (!CGRectEqualToRect(statusBarFrame, CGRectZero)) {
    UIInterfaceOrientation currentOrientation = rootViewController.interfaceOrientation;
    if (UIInterfaceOrientationIsPortrait(currentOrientation)) {
        // If portrait need to shrink height
        newViewFrame.size.height -= statusBarFrame.size.height;
        if (currentOrientation == UIInterfaceOrientationPortrait) {
            // If not upside-down move down origin
            newViewFrame.origin.y += statusBarFrame.size.height;
        }
    } else { // Is landscape 
        // portrait shrink width
        newViewFrame.size.width -= statusBarFrame.size.width;
        if (currentOrientation == UIInterfaceOrientationLandscapeLeft) {
            // If the status bar is on the left side of the window move origin
            newViewFrame.origin.x += statusBarFrame.size.width;
        }
    }
}
view.frame = newViewFrame; // pass new frame 
}
Run Code Online (Sandbox Code Playgroud)

调用方法(消息):

 if ([[UIApplication sharedApplication] isStatusBarHidden]) {
        [self statusBar:NO];
 } else {
        [self statusBar:YES];
 }
Run Code Online (Sandbox Code Playgroud)