問題:
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)載請注明出處