iOS開發(fā) 關(guān)于iOS11 設(shè)置導(dǎo)航欄透明或者隨偏移量改變透明度出現(xiàn)BUG

問題:

iOS 11更新后很多盆友的導(dǎo)航欄透明度設(shè)置都失效了。在iOS11之前很多常見的用法是


_barImageView = self.navigationController.navigationBar.subviews.firstObject.alpha;

獲取這個子視圖之后直接修改它的透明度,然后再監(jiān)聽的方法中:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
      CGFloat minAlphaOffset = 0;
      CGFloat maxAlphaOffset = 200;
      CGFloat offset = scrollView.contentOffset.y;
      CGFloat alpha = (offset - minAlphaOffset) / (maxAlphaOffset -   minAlphaOffset);
      NSLog(@"%f",alpha);
      _barImageView.alpha = alpha;
}

在iOS11之后,由于導(dǎo)航欄的結(jié)構(gòu)改變,導(dǎo)致了導(dǎo)航欄視圖的層級會有所改變。這樣的設(shè)置雖然能生效,但是我們的需求是在當(dāng)前界面被Push出來的時候,此時偏移量是0,所以要求導(dǎo)航欄的透明度是0,隨著便宜量變大,讓導(dǎo)航欄的透明度逐漸增加。
此種方法,會發(fā)現(xiàn)當(dāng)前界面push出來之后,默認(rèn)的導(dǎo)航欄透明度還是在的,不是透明的狀態(tài),即便我們在
-(void)viewWillAppear:(BOOL)animated 方法中設(shè)置_barImageView.alpha = 0 也不會生效。通過斷點你會發(fā)現(xiàn),在-(void)viewDidAppear:(BOOL)animated 方法中,_barImageView.alpha 又被賦值等于了1,并且當(dāng)前界面在滾動到alpha=0.5時push到其他界面之后,再pop回當(dāng)前界,會出現(xiàn)同樣的問題,當(dāng)前界面導(dǎo)航欄的透明度也會先被賦值為1.

解決辦法

實際上無論導(dǎo)航欄層級如何變化,我們只需要知道navigationBar有個方法setBackgroundImage可以設(shè)置導(dǎo)航欄背景圖,我們可以通過設(shè)置背景圖的透明度來改變導(dǎo)航欄的透明度。
1.添加記錄偏移量的成員變量

@property (nonatomic , assign) CGFloat offset;

2.在viewWillAppear方法中設(shè)置navigationBar的

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    //根據(jù)上次保存的偏移量生成相對應(yīng)透明度的圖片并賦值給navigationBar.setBackgroundImage
    [self.navigationController.navigationBar
     setBackgroundImage:[self createImageWithColor:[UIColor colorWithRed:38/255.0 green:137/255.0 blue:247/255.0 alpha:(_offset / 64)>0.99?0.99:(_offset / 64)]] forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar
     setShadowImage:[UIImage new]]; //取消navigationBar的分割線
}

3.在scrollViewDidScroll方法中,根據(jù)偏移量進(jìn)行賦值。

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    _offset = scrollView.contentOffset.y;//38,137,247
    [self.navigationController.navigationBar
     setBackgroundImage:[self createImageWithColor:[UIColor colorWithRed:38/255.0 green:137/255.0 blue:247/255.0 alpha:(_offset / 64)>0.99?0.99:(_offset / 64)]] forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar
     setShadowImage:[UIImage new]];
}

4.在viewWillDisappear方法中取消對navigationBar.setBackgroundImage的圖片的設(shè)置,恢復(fù)其他界面navigationBar的樣子。

    [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setShadowImage:nil];

好了,這樣就能達(dá)到我們想要的效果了。如果你想讓滾動到某個便宜量的時候,修改導(dǎo)航欄的字體顏色和狀態(tài)欄的顏色為白色,還可以在scrollViewDidScroll:(UIScrollView *)scrollView方法中加上:

 if (_offset > 136) {
        [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
        //標(biāo)題顏色
        self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]};
        //導(dǎo)航欄子控件顏色
        self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    }else{
        [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
        //標(biāo)題顏色
        self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor blackColor]};
        //導(dǎo)航欄子控件顏色
        self.navigationController.navigationBar.tintColor = [UIColor blackColor];
    }

但是注意如果想讓 [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent 此設(shè)置生效,必須修改info.plist中的View controller-based status bar appearance 為NO,才可以的。

另外,需要在viewWillAppear 和 viewWillDisappear 方法中對 導(dǎo)航欄的字體顏色和狀態(tài)欄的顏色進(jìn)行修改或者回復(fù)才能保證在 push 或者 pop的時候不會影響到其他界面。

作者:又是一個程序猿
歡迎大家討論分享
轉(zhuǎn)載請注明出處

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

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

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