【问题标题】:How to hide/show status bar and navigation bar by fading in/out at the same time like the Photos app in iOS 7?如何像 iOS 7 中的照片应用一样通过同时淡入/淡出来隐藏/显示状态栏和导航栏?
【发布时间】:2014-03-13 21:21:47
【问题描述】:

我正在尝试通过同时淡入和淡出来隐藏和显示状态栏和导航栏,就像 iOS 7 中的照片应用程序一样。我的隐藏部分正常工作,但我遇到了麻烦与展示部分。问题是当我显示导航栏时,它最初的定位好像状态栏不存在一样。在淡入结束时,它被正确定位(它向下移动为状态栏腾出空间)。如何在整个动画中正确定位导航栏?

这里有一些代码勾勒出我目前的方法:

在某些视图控制器中,我通过覆盖一些 UIViewController 方法来控制状态栏是否隐藏:

- (BOOL)prefersStatusBarHidden {
    return self.forcedStatusBarHidden;
}

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationFade;
}

为了同时隐藏状态栏和导航栏,我在同一个动画块中进行:

void (^animations)() = ^() {
    theNavigationController.navigationBar.hidden = YES;

    someViewController.forcedStatusBarHidden = YES;
    [someViewController setNeedsStatusBarAppearanceUpdate];
};
[UIView transitionWithView:theNavigationController.navigationBar.superview
                  duration:0.5
                   options:UIViewAnimationOptionCurveEaseInOut
                           | UIViewAnimationOptionTransitionCrossDissolve
                           | UIViewAnimationOptionAllowAnimatedContent
                animations:animations
                completion:nil];

(注意我使用 theNavigationController.navigationBar.hidden = YES 而不是 [theNavigationController setNavigationBarHidden:YES animated:YES] 因为我希望导航栏淡出而不是滑动向上。另外,由于某种原因,不包括 UIViewAnimationOptionAllowAnimatedContent 选项并没有什么不同。)

但是如果我做一些类似的事情来同时显示状态栏和导航栏,我就会遇到前面描述的问题。

void (^animations)() = ^() {
    someViewController.forcedStatusBarHidden = NO;
    [someViewController setNeedsStatusBarAppearanceUpdate];

    theNavigationController.navigationBar.hidden = NO;
};
[UIView transitionWithView:theNavigationController.navigationBar.superview
                  duration:0.5
                   options:UIViewAnimationOptionCurveEaseInOut 
                           | UIViewAnimationOptionTransitionCrossDissolve
                           | UIViewAnimationOptionAllowAnimatedContent
                animations:animations
                completion:nil];

我最接近让它看起来正确的方法是按顺序显示条形而不是在同一个动画块中:

someViewController.forcedStatusBarHidden = NO;
[someViewController setNeedsStatusBarAppearanceUpdate];

void (^animations)() = ^() {
    theNavigationController.navigationBar.hidden = NO;
};
[UIView transitionWithView:theNavigationController.navigationBar.superview
                  duration:0.5
                   options:UIViewAnimationOptionCurveEaseInOut 
                           | UIViewAnimationOptionTransitionCrossDissolve
                           | UIViewAnimationOptionAllowAnimatedContent
                animations:animations
                completion:nil];

但现在这些条不会一起淡入。 (编辑:如果我将前两行放在他们自己的动画块中以强制状态栏淡入的动画持续时间,我会得到导航栏的原始问题。)我该如何解决这个问题?

注意:我正在为导航栏使用自定义背景图像。如果我只是为导航栏使用默认的磨砂/模糊背景,另一个问题是背景在应该淡入时是不可见的,并且在淡入动画结束时突然出现。如果我也能在磨砂/模糊背景下使用它,那就太好了。

另一个注意事项:以防万一,导航控制器显示为 theNavigationController.modalPresentationStyle = UIModalPresentationCustom

【问题讨论】:

  • 您是否尝试过在动画块中将导航栏的 alpha 设置为 0?
  • 没有。我试试看。
  • @NoahWitherspoon 在动画块中将导航栏的 alpha 设置为 0 会在淡入和现在淡出时给我同样的问题。导航栏似乎想尽可能地拥抱顶部,但是使用 [UIView transitionWithView...] 时,事情似乎有所不同。
  • @NoahWitherspoon 将导航栏的 alpha 设置为 1 而不是将 hidden 属性设置为 NO 修复了导航栏的磨砂/模糊背景不淡入的问题。

标签: objective-c ios7 uinavigationcontroller uinavigationbar


【解决方案1】:

我找到了自己问题的答案。诀窍是禁用动画,只是为了在淡入动画期间设置导航栏的框架、边界和中心。这是通过继承 UINavigationBar 并在设置框架、边界和中心时有条件地使用 [UIView performWithoutAnimation...] 来完成的。例如:

- (void)setFrame:(CGRect)frame
{
    if (self.shouldAnimateDimensions) {
        [super setFrame:frame];
    }
    else {
        [UIView performWithoutAnimation:^{
            [super setFrame:frame];
        }];
    }
}

然后淡入代码变成:

void (^animations)() = ^() {
    // myNavigationBar is theNavigationController.navigationBar
    myNavigationBar.shouldAnimateDimensions = NO;

    someViewController.forcedStatusBarHidden = NO;
    [someViewController setNeedsStatusBarAppearanceUpdate];

    myNavigationBar.shouldAnimateDimensions = YES;

    theNavigationController.navigationBar.hidden = NO;
};
[UIView transitionWithView:theNavigationController.navigationBar.superview
                  duration:0.5
                   options:UIViewAnimationOptionCurveEaseInOut 
                           | UIViewAnimationOptionTransitionCrossDissolve
                           | UIViewAnimationOptionAllowAnimatedContent
                animations:animations
                completion:nil];

【讨论】:

    猜你喜欢
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    相关资源
    最近更新 更多