Navigation Bar 渐隐动画实现

Navigation Bar 透明动画实现

目前很流行流行的UI效果,监听滚动,导航条渐隐的UI效果实现,很多APP都有实现,比如美团外卖的首页模块,新浪微博的个人详情页面。

盗的效果图

设置self.view全屏

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self configVCFullScreen];
    
    ... 
}

/// 设置 self.view 全屏
- (void)configVCFullScreen
{
    self.edgesForExtendedLayout = UIRectEdgeAll;
    self.extendedLayoutIncludesOpaqueBars = YES;
    self.modalPresentationCapturesStatusBarAppearance = YES;
    self.automaticallyAdjustsScrollViewInsets = NO;
}

设置 Naivgation Bar 的透明度

- (void)configNavigationBar
{
    ...
    
    // KVO 监听 offset ,计算透明图    
    @weakify(self);
    [[[RACObserve(self.tableView, contentOffset) takeUntil:[self rac_signalForSelector:@selector(viewWillDisappear:)]]filter:^BOOL(NSValue *value) {
        return value.CGPointValue.y <= 500;
    }] subscribeNext:^(NSValue *value) {
        @strongify(self);
        CGFloat alpha = MAX(0, self.tableView.contentOffset.y / ([UIScreen width] / 16.0f * 9.0f - 64));
        [self setNavigationBarAlpha:alpha];
          
          ...
          
    }];
}

- (void)setNavigationBarAlpha:(CGFloat)alpha
{
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor colorWithWhite:1.0f alpha:alpha]] forBarMetrics:UIBarMetricsDefault];
}

去掉 Navigation Bar 的底阴影线

/// 去掉 navigation bar 底线
self.navigationController.navigationBar.shadowImage = [UIImage new]; 

如何设置 Status Bar的颜色

// 设置Status Bar 字体为黑色
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];

// 设置Status Bar 字体为白色
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

完整细节代码

#pragma mark - View Controller Life Cycle
- (void)viewDidLoad
{
    [super viewDidLoad];    
    self.tableView.forbidAutoGa = YES;
    // 导航栏透明
    [self configVCFullScreen];
    
    ...
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // 设置透明度相关
    [self configNavigationBar];
    
    ...
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    CGFloat alpha = MAX(0, self.tableView.contentOffset.y / ([UIScreen width] / 16.0f * 9.0f - 64));
    if (alpha < 0.5) {
        // viewWillAppear 里面更改没有效果,可能是我们公司业务的父类有处理
        [self setupLightStyleAppearance];
    }
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    //页面消失前恢复之前的设置,避免对其他页面造成影响
    [self resumeNavigationBar];
}

#pragma mark - Navigation Bar config

- (void)configNavigationBar
{
    if (!_oldShadowImage) {
        self.oldShadowImage = [self.navigationController.navigationBar shadowImage];
    }
    if (!_oldBackImage && [self.navigationItem.leftBarButtonItem.customView isKindOfClass:[UIButton class]]) {
        self.backBtn = self.navigationItem.leftBarButtonItem.customView;
        self.oldBackImage = self.backBtn.imageView.image;
    }
    
    @weakify(self);
    [[[RACObserve(self.tableView, contentOffset) takeUntil:[self rac_signalForSelector:@selector(viewWillDisappear:)]]filter:^BOOL(NSValue *value) {
        return value.CGPointValue.y <= 500;
    }] subscribeNext:^(NSValue *value) {
        @strongify(self);
        CGFloat alpha = MAX(0, self.tableView.contentOffset.y / ([UIScreen width] / 16.0f * 9.0f - 64));
        [self setNavigationBarAlpha:alpha];
        [self setupTopBarsAppearanceWithAlpha:alpha];
    }];
}

- (void)configVCFullScreen
{
    self.edgesForExtendedLayout = UIRectEdgeAll;
    self.extendedLayoutIncludesOpaqueBars = YES;
    self.modalPresentationCapturesStatusBarAppearance = YES;
    self.automaticallyAdjustsScrollViewInsets = NO;
}

- (void)setNavigationBarAlpha:(CGFloat)alpha
{
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor colorWithWhite:1.0f alpha:alpha]] forBarMetrics:UIBarMetricsDefault];
}

- (void)setupTopBarsAppearanceWithAlpha:(CGFloat)alpha
{
    if (alpha < 0.5 && self.navigationController.navigationBar.shadowImage == self.oldShadowImage) {
        [self setupLightStyleAppearance];
    } else if ( alpha > .5 && self.navigationController.navigationBar.shadowImage != self.oldShadowImage) {
        [self setupDarkStyleAppearance];
    }
}

- (void)setupLightStyleAppearance
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];//!< statusbar
    self.navigationController.navigationBar.shadowImage = [UIImage new]; //!< navigation bar 底线
    self.title = @"";
    
    [self.backBtn setImage:[UIImage imageNamed:R_hotel_title_icon_back_light] forState:UIControlStateNormal];
    [self.buttonForShare setImage:[UIImage imageNamed:R_hotel_title_icon_share_light] withHighLightStyle:ButtonHighLightStyleDark];
}

- (void)setupDarkStyleAppearance
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
    self.navigationController.navigationBar.shadowImage = self.oldShadowImage;
    self.title = self.product.title;
    
    [self.backBtn setImage:self.oldBackImage ? : [UIImage imageNamed:@"detail_topbar_icon_back"] forState:UIControlStateNormal];
    [self.buttonForShare setImage:[UIImage imageNamed:R_Title_icon_Share] withHighLightStyle:ButtonHighLightStyleDark];
}

- (void)resumeNavigationBar
{
    [self setNavigationBarAlpha:1];
    [self.navigationController.navigationBar setShadowImage:self.oldShadowImage];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}

你可能感兴趣的:(Navigation Bar 渐隐动画实现)