代码之家  ›  专栏  ›  技术社区  ›  Ortwin Gentz

如何同时滑入/滑出状态栏和导航栏?

  •  4
  • Ortwin Gentz  · 技术社区  · 14 年前

    我想使用幻灯片效果同时显示和隐藏状态栏和导航栏。

    我就是这样尝试的:

    [[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationSlide];
    [self.navigationController setNavigationBarHidden:hide animated:animated];
    

    但是,两个动画的持续时间不相同。状态栏动画需要更长的时间。 我找不到方法来指定两个动画的持续时间。 我错过什么明显的东西了吗?

    7 回复  |  直到 6 年前
        1
  •  5
  •   nacho4d    12 年前

    hidden 设置正确。所以这对我有用:

    隐藏动画作品/看起来不错耶!!。

    显示动画是可以的,(我希望我可以使状态栏幻灯片与导航栏,但至少我们看不到差距了。 :D

    - (void)toggleFullscreen {
    
        UINavigationBar *navBar = self.navigationController.navigationBar;
        CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
        float animationDuration;
        if(statusBarFrame.size.height > 20) { // in-call
            animationDuration = 0.5;
        } else { // normal status bar 
            animationDuration = 0.6;
        }
    
        _fullscreen = !_fullscreen;
        if (_fullscreen) { 
            // Change to fullscreen mode
            // Hide status bar and navigation bar
            [[UIApplication sharedApplication] setStatusBarHidden:YES
                                                    withAnimation:UIStatusBarAnimationSlide];
            [UIView animateWithDuration:animationDuration animations:^{
                navBar.frame = CGRectMake(navBar.frame.origin.x,
                                      -navBar.frame.size.height,
                                      navBar.frame.size.width,
                                      navBar.frame.size.height);
            } completion:^(BOOL finished) {
                [self.navigationController setNavigationBarHidden:YES animated:NO];
            }];
    
        } else {
            // Change to regular mode
            // Show status bar and navigation bar
            [[UIApplication sharedApplication] setStatusBarHidden:NO
                                                    withAnimation:UIStatusBarAnimationSlide];
            [UIView animateWithDuration:animationDuration animations:^{
                 navBar.frame = CGRectMake(navBar.frame.origin.x,
                                           statusBarFrame.size.height,
                                           navBar.frame.size.width,
                                           navBar.frame.size.height);
            } completion:^(BOOL finished) {
                [self.navigationController setNavigationBarHidden:NO animated:NO];
            }];
    
        }
    
    }
    
        2
  •  2
  •   ios-lizard    12 年前

    这就是我如何解决我的应用程序这个问题。

        CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
    
        // delta is the amount by which the nav bar will be moved
        delta = statusBarFrame.size.height + self.navigationController.navigationBar.frame.size.height;
    
        if(statusBarFrame.size.height>20) { // in-call
            animationDuration = 0.5;
        }
        else { // normal status bar 
            animationDuration = 0.6;
        }
    
        // hide status bar
        [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
    
        // hide nav bar
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:animationDuration];
    
        self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -delta);
    
        [UIView commitAnimations];
    
        3
  •  1
  •   Ortwin Gentz    14 年前

    fix it .

    当然,一个解决方法是使用alpha褪色,正如以法莲所建议的那样。如果您坚持使用滑动行为,我发现最好只设置导航栏的动画并隐藏/显示状态栏,而不使用任何动画。这看起来比滑动状态栏要好得多,因为在动画期间状态栏之间的间隙非常明显。

        4
  •  1
  •   ioblomov    11 年前

    注意,navigationBar是一个outlet,statusBarHeight是一个实例变量float。

    - (IBAction)toggleControls:(id)sender {
        BOOL isHidden = ! [UIApplication sharedApplication].statusBarHidden;
        if (isHidden)
            statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
        [UIView animateWithDuration:[UIApplication sharedApplication].statusBarOrientationAnimationDuration animations:^{
            self.navigationBar.frame = CGRectMake(self.navigationBar.frame.origin.x,
                                                  isHidden ? -self.navigationBar.frame.size.height : statusBarHeight,
                                                  self.navigationBar.frame.size.width,
                                                  self.navigationBar.frame.size.height);
        }];
        [[UIApplication sharedApplication] setStatusBarHidden:isHidden withAnimation:UIStatusBarAnimationSlide];
    }
    
        5
  •  1
  •   RY_ Zheng    8 年前

    nacho4d的回答几乎是我想要的,但是他在导航栏出现之前改变了导航栏的框架。所以我们看不到过渡动画。看起来导航栏突然出现了。更重要的是,在显示时,statusBarFrame.size.height等于0

    [[UIApplication sharedApplication] setStatusBarHidden:NO
                                                withAnimation:UIStatusBarAnimationSlide];
        [UIView animateWithDuration:animationDuration animations:^{
             navBar.frame = CGRectMake(navBar.frame.origin.x,
                                       statusBarFrame.size.height,
                                       navBar.frame.size.width,
                                       navBar.frame.size.height);
        } completion:^(BOOL finished) {
            [self.navigationController setNavigationBarHidden:NO animated:NO];
        }];
    

    在显示时,我们希望可以使状态栏与导航栏一起滑动。 这是我的答案

            UINavigationBar *navBar = self.navigationController.navigationBar;
            [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide];
    
            [UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                // make navigationBar visual
                if (!hidden)
                {
                    [self.navigationController setNavigationBarHidden:hidden animated:NO];
                }
    
                navBar.frame = CGRectMake(navBar.frame.origin.x,
                                          hidden ? -navBar.frame.size.height : 20,
                                          navBar.frame.size.width,
                                          navBar.frame.size.height);
            } completion:^(BOOL finished) {
                if (hidden)
                {
                    [self.navigationController setNavigationBarHidden:hidden animated:NO];
                }
            }];
    
    1. 隐藏 等于 . 我们应该先改变导航栏的框架,然后隐藏导航栏。
    2. 显示时,以及 等于
    3. 我们选择 ,使它看起来更好。
        6
  •  0
  •   The Windwaker    10 年前

    可以使用实例变量执行以下操作:

    self.navigationController setNavigationBarHidden:hide animated:animated];
    _shouldHideStatusBar = hide;
    

    并实现以下功能:

    - (BOOL)prefersStatusBarHidden{
        return _shouldHideStatusBar;
    }
    

    这个 设置导航栏idden:animated 首选状态栏隐藏 功能。如果没有,可以使用以下UIViewController方法调用它:

    [self setNeedsStatusBarAppearanceUpdate];
    

    当然,您可以使用以下选项选择状态栏隐藏动画样式:

    - (UIStatusBarAnimation) preferredStatusBarUpdateAnimation {
        return UIStatusBarAnimationSlide;
    }
    
        7
  •  0
  •   Pang Lokesh Desai    7 年前

    这不是一个很好的答案,但它的工作。所以我做的是:

    // This method gets called by whatever action you want
    
    - (void) toggleShowStatusNavBars:(id)sender {
    
        // Assuming you have a ivar called barsHidden
    
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.4]; // This is IMPORTANT, 0.4s
    
        self.navigationController.navigationBar.alpha = (barsHidden?1.0:0.0);  
    
        barsHidden = !barsHidden; 
    
        [UIView setAnimationDelegate:self];
        [UIView setAnimationWillStartSelector:@selector(setStatusBarHidden)];
    
        [UIView commitAnimations];
    }
    
    - (void) setStatusBarHidden {
        [[UIApplication sharedApplication] setStatusBarHidden:barsHidden animated:YES];
    }
    

    这将基本上同步动画的开始(因为您正在调用 setStatusBarHidden 在导航栏动画的开头。关键是状态栏动画似乎需要0.4秒。

    这对我有效,但如果你找到一个更好的方法,请张贴在这里。