4

在加载视图隐藏状态栏时,我遇到了一个奇怪的问题。如果我在 ViewDidLoad 方法中添加以下方法,状态栏将从视图中完全删除:

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

但是,如果我在 IBAction 或其他方法中调用此方法,状态栏仍会滑开,但会留下一个与自身高度相同的黑条。

我曾考虑将整个视图向上移动 20 像素,但这真的可以解决问题吗?我不想只重叠一个黑条,以防在未来的操作系统升级中状态栏高度发生变化。

状态栏离开黑条

4

5 回答 5

3

对任何数字进行硬编码总是与未来的证明背道而驰。你的担心是正确的。正确处理 statusBar 的隐藏有一些技巧。但是所有需要的信息都是可用的。

例如,UIApplication单例有一个名为的属性statusBarFrame,这正是它听起来的样子,aCGRectstatusBar框架。很酷的是,一旦你调用setStatusBarHidden:withAnimation:了该属性,它就会给你新的帧,甚至在动画完成之前。所以实际上你只剩下一些基本的数学来调整view's frame

简而言之,您的直觉是正确的;总是实时计算。

我用这样的类别方法取得了很好的成功。(即使在模拟器中切换通话状态栏(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
于 2012-10-17T05:50:51.897 回答
0

是的,将视图移动 20 像素应该可以解决您的问题。黑色是没有任何东西可以显示,而不是真正的黑条。

至于潜在的状态高度变化,如果发生这种情况,此修复将不起作用,因为视图将移动新状态栏的高度。如果发生这种情况,您将不得不为不同的状态栏添加不同的偏移量,或者找到一个全新的解决方案。

于 2012-10-17T04:04:54.307 回答
0

viewWillAppear

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];

viewDidAppear中,您可以插入:

self.view.window.rootViewController.view.frame = [UIScreen mainScreen].applicationFrame;

viewWillDisappear

[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
于 2013-09-19T20:10:57.800 回答
0

你为什么打电话给这个viewDidLoad

在 loadView 中试试?

- (void)loadView {
    [super loadView];

    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
于 2012-10-17T00:23:23.863 回答
0

我可以通过调用来解决这个问题:

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

正如其他人在展示显示黑条的视图控制器之前推荐的那样。

例如,如果我有一个呈现的动作ViewController,我会这样称呼它:

- (IBAction)presentViewController:(id)sender {
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
    ViewController *vc = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    [self presentViewController:vc animated:YES completion:nil];
}
于 2016-08-15T19:05:39.257 回答