動態(tài)設置導航欄透明度

一直看到好多的app都有狀態(tài)欄隨視圖的滑動,透明度動態(tài)改變,跳轉入其它視圖則正常顯示導航欄,今天有點時間,就自己動手實現(xiàn)一下,本以為沒什么難度,殊不知還是有些點需要注意的。
先看一下效果:

2017-09-21 17_01_55.gif

下面我們一步一步剖析:
1、設置導航顏色,下邊兩種設置導航方法,都可以動態(tài)改變透明度

[[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、視圖出現(xiàn)時處理

- (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));
        
        //這里需要區(qū)分,在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];
        
    }
}

這里為了使導航在恰當?shù)臅r機顯示正確的顏色,添加了Translucent屬性的設置,這個值默認是YES,此時導航欄有透明效果,若是設置為NO則無法動態(tài)改變透明度,此處需要注意

Translucent為YES時tableView的起始是從屏幕頂端開始的,若是設置為NO則是從64高度開始的,這個在透明度為1的臨界點時會出現(xiàn)問題,需要修正修正代碼:

//這里需要區(qū)分,在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];
    }
    
}

至此達到了我們想要的效果,即當期視圖可動態(tài)導航透明度,其它視圖不受影響正常顯示

Demo地址

添加修正:
由于設置Translucent時tableciew的偏移量改變,則還會調用活動的代理方法,會重新的設置導航的透明度,所以必須

- (void)viewWillDisappear:(BOOL)animated{

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

然后在ciewwillAppear重新添加代理

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 前言 在開發(fā)過程中,經(jīng)常會碰到控制器對應的導航欄的背景顏色不一致或者需要讓導航欄背景透明的需求。在導航控制器pus...
    漸z閱讀 2,893評論 0 8
  • 在我做 Android 開發(fā)之前,我就發(fā)現(xiàn)有些 App 的狀態(tài)欄和導航欄有透明效果,或者是沉浸式效果,比如說酷安的...
    杰克船長愛蘿莉閱讀 1,137評論 0 8
  • 引 如我在傳送門:iOS導航欄切換界面時隱藏和顯示[http://www.lxweimin.com/p/03170...
    Cloudox_閱讀 11,535評論 14 62
  • 每一個走進過彩票店的擁躉,都有過懷揣兩塊錢,胸懷500W的夢想。買過老足彩的球迷都有這樣的體會:你頭次中了任九頭獎...
    白博生閱讀 1,265評論 0 0
  • 大學的復習大多是在最后一兩周來解決的。有的人考試前一個月都怕的不要不要的,而有的人完全無所畏懼,不到考試前一個...
    傲嬌的believe閱讀 334評論 2 1