iOS監(jiān)聽UIScrollView使導(dǎo)航欄透明度漸變

1、效果展示

1.gif

2、實(shí)現(xiàn)原理

實(shí)現(xiàn)原理其實(shí)就是觀察UIScrollView的contentOffset的y值,根據(jù)y值的變化來不斷的設(shè)置導(dǎo)航欄背景色的alpha值,從而使其達(dá)到導(dǎo)航欄透明度漸變的效果。

3、細(xì)節(jié)說明

擴(kuò)展UINavigationBar

首先,我們發(fā)現(xiàn)直接修改UINavigationBar的背景顏色是不行的。因?yàn)樵赨INavigationBar的高度是44,其上面的20px是狀態(tài)欄,如果單純的setBackgroundColor只是漸變狀態(tài)欄下邊的44px的顏色,看起來效果像截?cái)嗔艘粯?。所以,我們需要擴(kuò)展UINavigationBar這個(gè)類,在該類添加一個(gè)view,使得該view高度為64px并且是在最上層顯示,目的是把狀態(tài)欄給遮擋住。部分代碼如下:

- (void)cnSetBackgroundColor:(UIColor *)backgroundColor
{
    if (!self.overlay) {
        [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
        self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, CGRectGetHeight(self.bounds) + 20)];
        self.overlay.userInteractionEnabled = NO;
        self.overlay.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        [self insertSubview:self.overlay atIndex:0];
    }
    
    self.overlay.backgroundColor = backgroundColor;
}

其中,overlay是通過runtime運(yùn)行時(shí)添加的一個(gè)關(guān)聯(lián)對(duì)象。

設(shè)置UIScrollView的contentInset

因?yàn)樾枰鶕?jù)滾動(dòng)距離變化來設(shè)置導(dǎo)航欄的透明度,所以初始情況下,需要設(shè)置好UIScrollView里的contentInset值

監(jiān)聽UIScrollView的contentOffset.y值

根據(jù)UIScrollView 的delegate方法scrollViewDidScroll,我們能實(shí)時(shí)獲得contentOffset.y值,根據(jù)該值的變化對(duì)剛才擴(kuò)展的UINavigationBar的背景色的alpha值,做相應(yīng)的變化,具體實(shí)現(xiàn):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    UIColor *color = [UIColor colorWithRed:45/255.0 green:45/255.0 blue:45/255.0 alpha:1];
    CGFloat offsetY = scrollView.contentOffset.y;
    if (offsetY >= - _halfHeight - 64) {
        CGFloat alpha = MIN(1, (_halfHeight + 64 + offsetY)/_halfHeight);
         [self.navigationController.navigationBar cnSetBackgroundColor:[color colorWithAlphaComponent:alpha]];
        
        _descriptionView.alpha = 1 - alpha;
    } else {
        [self.navigationController.navigationBar cnSetBackgroundColor:[color colorWithAlphaComponent:0]];
    }
}

4、補(bǔ)充說明

需要在viewWillAppear方法中去掉導(dǎo)航欄的底邊線,也就是那一條區(qū)分的橫線。

[self.navigationController.navigationBar setShadowImage:[UIImage new]];

為避免返回到其他頁面后,還是沿用該導(dǎo)航欄樣式,所以需要在viewWillDisappear的時(shí)候,還原之前的樣式,也就是把overlay給去掉,具體看代碼實(shí)現(xiàn)。

5、Github代碼

GitHub下載

2017/02/27 更新

看到讀者評(píng)論說,用了后會(huì)使得導(dǎo)航欄的Item消失不見的,我自己測(cè)試了一下,發(fā)現(xiàn)在iOS10上面會(huì)出現(xiàn)這個(gè)問題,估計(jì)UINavigationBar在iOS10上面的布局可能有了變化,我后來想了另外一個(gè)更投機(jī)的方法去實(shí)現(xiàn)這個(gè)功能,不需要通過Category多添加UINavigationBar里面的背景View去實(shí)現(xiàn),而是通過

self.navigationController.navigationBar.barTintColor

去設(shè)置顏色,而通過使用

[[[self.navigationController.navigationBar subviews] objectAtIndex:0] setAlpha:0];

找到navigationBar的背景view,然后設(shè)置alpha值。已經(jīng)更新到GitHub上了,各位看官可以去下載看看。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • *7月8日上午 N:Block :跟一個(gè)函數(shù)塊差不多,會(huì)對(duì)里面所有的內(nèi)容的引用計(jì)數(shù)+1,想要解決就用__block...
    炙冰閱讀 2,752評(píng)論 1 14
  • IOS的項(xiàng)目多數(shù)會(huì)遇到控制狀態(tài)欄和導(dǎo)航欄的問題,比如隱藏狀態(tài)欄、控制狀態(tài)欄的文字顏色等,導(dǎo)航欄也有同樣需求。本文總...
    YHWXQ簡(jiǎn)簡(jiǎn)單單的生活閱讀 1,871評(píng)論 1 8
  • 1、如何制作電子郵件鏈接? 你的回答: <mail>xxx@yyy</mail> 正確答案: 2、如何產(chǎn)生帶有圓點(diǎn)...
    一只dororo閱讀 709評(píng)論 0 1
  • 若我再見你, 時(shí)隔經(jīng)年。 我將何以賀你? 以眼淚, 以沉默。
    荒木閱讀 227評(píng)論 0 0
  • 起步 Shiro官方網(wǎng)站這是一個(gè)很簡(jiǎn)單的安全框架我們的目標(biāo)是搭建一個(gè)無session的認(rèn)證授權(quán)系統(tǒng) 項(xiàng)目整合 Ma...
    hutou閱讀 996評(píng)論 2 0

友情鏈接更多精彩內(nèi)容