【问题标题】:Hiding status bar after view has loaded leaves black bar加载视图后隐藏状态栏会留下黑条
【发布时间】:2012-10-16 23:52:27
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您是否尝试将其设置为viewDidAppear:?除非您有复杂的视图配置,否则这应该可以工作。

标签: iphone objective-c ios


【解决方案1】:

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

例如,UIApplication 单例有一个名为statusBarFrame 的属性,这正是它听起来的样子,statusBar 的框架的CGRect。很酷的是,一旦你调用了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

【讨论】:

    【解决方案2】:

    您为什么在viewDidLoad 中调用这个?

    在 loadView 中试试?

    - (void)loadView {
        [super loadView];
    
        [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
    }
    

    【讨论】:

    • 好吧,我在这里调用它是为了测试。我真的希望能够在一个方法中调用它。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      viewWillAppear:

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

      viewDidAppear,你可以插入:

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

      viewWillDisappear:

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多