美文网首页
动态设置导航栏透明度

动态设置导航栏透明度

作者: 黑炭长 | 来源:发表于2017-09-21 17:35 被阅读287次

一直看到好多的app都有状态栏随视图的滑动,透明度动态改变,跳转入其它视图则正常显示导航栏,今天有点时间,就自己动手实现一下,本以为没什么难度,殊不知还是有些点需要注意的。
先看一下效果:

2017-09-21 17_01_55.gif

下面我们一步一步剖析:
1、设置导航颜色,下边两种设置导航方法,都可以动态改变透明度

[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:45/255.0 green:45/255.0 blue:45/255.0 alpha:1]];

[[UINavigationBar appearance] setBackgroundImage:[[UIImage imageNamed:@"顶部栏_7.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:10] forBarMetrics:UIBarMetricsDefault];

2、设置视图偏移量

_halfHeight = [UIScreen mainScreen].bounds.size.height * 0.5 - 64;
    [_mytableView setContentInset:UIEdgeInsetsMake(_halfHeight, 0, 0, 0)];

3、视图出现时处理

- (void)viewWillAppear:(BOOL)animated{

    [super viewWillAppear:animated];
    
    self.navigationController.navigationBar.barStyle = UIBarStyleBlack;//导航栏的背景色是黑色, 字体为白色
    [self scrollViewDidScroll:self.mytableView];//开始就处理
    [self.navigationController.navigationBar setShadowImage:[UIImage new]];//用于去除导航栏的底线,也就是周围的边线
    
}

4、主要处理方法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    
    CGFloat offsetY = scrollView.contentOffset.y;
    NSLog(@"oooooo%f",offsetY);
    if (offsetY >= - _halfHeight-64) {
        CGFloat alpha = MIN(1, (_halfHeight + offsetY + 64)/(_halfHeight+64));
        
        //这里需要区分,在translicent 切换值时,偏移量相差64
        if (self.navigationController.navigationBar.translucent && offsetY >= -64) {
            alpha = 1;
        }
        
        [[[self.navigationController.navigationBar subviews] objectAtIndex:0] setAlpha:alpha];//设置显示层视图透明度
        
        
        
        if (alpha == 1) {
            [self.navigationController.navigationBar setTranslucent:NO];
            
        }else{
            
            [self.navigationController.navigationBar setTranslucent:YES];
        }
        
    } else {
        
        [self.navigationController.navigationBar setTranslucent:YES];
        [[[self.navigationController.navigationBar subviews] objectAtIndex:0] setAlpha:0];
        
    }
}

这里为了使导航在恰当的时机显示正确的颜色,添加了Translucent属性的设置,这个值默认是YES,此时导航栏有透明效果,若是设置为NO则无法动态改变透明度,此处需要注意

Translucent为YES时tableView的起始是从屏幕顶端开始的,若是设置为NO则是从64高度开始的,这个在透明度为1的临界点时会出现问题,需要修正修正代码:

//这里需要区分,在translicent 切换值时,偏移量相差64
        if (self.navigationController.navigationBar.translucent && offsetY >= -64) {
            alpha = 1;
        }

本以为到这里就结束了,多想了一下,若是跳转其它视图,要正常显示,此时就要设置Translucent 为NO,为了对所有视图起作用,需添加UIViewController的分类,直接上代码:

+ (void)load{

    Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
    Method logViewWillAppear = class_getInstanceMethod(self, @selector(logViewWillAppear:));
    
    method_exchangeImplementations(viewWillAppear, logViewWillAppear);
}

- (void)logViewWillAppear:(BOOL)animated{

    [self logViewWillAppear:animated];
    
    if ([self isKindOfClass:[ViewController class]]) {
        [self.navigationController.navigationBar setTranslucent:YES];
    }else{
    
        [self.navigationController.navigationBar setTranslucent:NO];
    }
    
}

至此达到了我们想要的效果,即当期视图可动态导航透明度,其它视图不受影响正常显示

Demo地址

添加修正:
由于设置Translucent时tableciew的偏移量改变,则还会调用活动的代理方法,会重新的设置导航的透明度,所以必须

- (void)viewWillDisappear:(BOOL)animated{

    [super viewWillDisappear:animated];
    self.mytableView.delegate = nil;//必须加上
    [[[self.navigationController.navigationBar subviews] objectAtIndex:0] setAlpha:1];
}

然后在ciewwillAppear重新添加代理

相关文章

网友评论

      本文标题:动态设置导航栏透明度

      本文链接:https://www.haomeiwen.com/subject/ooctextx.html