4

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

这就是我尝试的方式:

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

但是,两个动画的持续时间并不相同。状态栏动画需要更长的时间。我发现无法指定任一动画的持续时间。我错过了什么明显的东西吗?

4

7 回答 7

5

hiddenios-lizard 的答案几乎是我想要的,但除非设置正确,否则在旋转设备时导航栏会重新出现。所以这对我有用:

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

显示动画是可以的,(我希望我可以让状态栏与导航栏一起滑动,但至少我们看不到差距了。: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];
        }];

    }

}
于 2012-02-22T04:50:18.920 回答
2

这就是我为我的应用程序解决此问题的方法。

    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];
于 2012-01-20T10:46:59.230 回答
1

显然,没有简单的解决方案可以做到这一点。苹果必须修复它

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

于 2011-01-14T14:27:46.060 回答
1

这是一个更简洁的方法,它使用系统常量来表示动画持续时间并处理传入呼叫。

请注意,navigationBar 是一个插座,而 statusBarHeight 是一个实例变量浮点数。

- (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];
}
于 2013-04-29T22:07:18.087 回答
1

nacho4d 的回答几乎是我想要的。但是,他在 navBar 可见之前改变了 navBar 的框架。所以我们看不到过渡动画。看起来navBar突然出现了。更何况,显示的时候statusBarFrame.size.height等于0。下面是他的代码:</p>

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

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

        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. 隐藏时,隐藏等于NO。我们应该先改变导航栏的框架,然后隐藏导航栏。
  2. 显示时,和隐藏等于YES。我们首先使 navBar 可视化,然后更改框架。
  3. 我们选择UIViewAnimationOptionCurveEaseOut,让它看起来更好。
于 2016-02-25T09:27:30.763 回答
0

您可以使用实例变量来执行此操作:

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

并实现以下功能:

- (BOOL)prefersStatusBarHidden{
    return _shouldHideStatusBar;
}

setNavigationBarHidden :animated函数会自动调用prefersStatusBarHidden函数。如果没有,您可以使用以下 UIViewController 的方法调用它:

[self setNeedsStatusBarAppearanceUpdate];

当然,您可以通过以下方式选择状态栏隐藏动画样式:

- (UIStatusBarAnimation) preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationSlide;
}
于 2014-08-21T12:40:01.170 回答
0

这不是一个答案,但它有效。所以我所做的是:

// 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秒。

这对我有用,但如果您找到更好的方法,请在此处发布。

于 2010-10-05T16:50:39.997 回答