视图加载后隐藏状态栏会留下黑色的条纹。

4

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

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

然而,如果我在IBAction或另一个方法中调用此方法,状态栏仍会滑动消失,但会留下与其相同高度的黑色条纹。
我考虑将整个视图上移20像素,但这真的是一种解决方法吗?我不想只是重叠一个黑色条纹,以防未来的操作系统升级更改状态栏高度。
图片:Status bar leaving black bar

你尝试在 viewDidAppear: 中设置它了吗?除非你有复杂的视图配置,否则这应该可以工作。 - John Estropia
5个回答

3
任何硬编码的数字都不利于未来的保护。您的担忧是正确的。正确处理隐藏状态栏有一些技巧,但所有必要的信息都是可用的。
例如,UIApplication单例有一个名为statusBarFrame的属性,它恰好是一个CGRectstatusBar的框架。很酷的是,一旦您调用setStatusBarHidden:withAnimation:,该属性将在动画完成之前给出新的框架。因此,您只需要进行一些基本的数学计算来调整viewframe
简而言之,您的直觉是正确的;始终实时计算。
我使用了像这样的分类方法取得了良好的成功。(即使在模拟器中切换呼叫状态栏(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

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];
}

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];

0

你为什么在viewDidLoad方法中调用这个函数?

试着在loadView方法中尝试一下?

- (void)loadView {
    [super loadView];

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

好的,我在那里调用它是为了测试目的。我真的想能够在一个方法中调用它。 - jcrowson

0

是的,将视图移动20像素应该可以解决您的问题。黑色表示没有任何内容可显示,而不是实际的黑色条。

至于可能的状态栏高度更改,如果发生这种情况,此修复程序将无法正常工作,因为视图将被新状态栏的高度移动。如果发生这种情况,您将不得不为不同的状态栏添加不同的偏移量,或者找到一个全新的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接