KVO 設置 navigationBar 漸變透明效果

本人有若干成套學習視頻, 可試看! 可試看! 可試看, 重要的事情說三遍 包含Java, 數(shù)據(jù)結構與算法, iOS, 安卓, python, flutter等等, 如有需要, 聯(lián)系微信tsaievan.

今天感冒了, 太特么難受了, 寫個小 demo 吧

不多說, 先看效果
navigationBar 漸變透明效果
思路其實很簡單,監(jiān)聽 tableView 的滾動范圍, 即 contentOffset 的 y 值,
  • 當 y 值 = 0時, navigationBar 先隱藏,
  • 當 y 剛剛大于0時, navigationBar 出現(xiàn)
  • 透明度其實就是 y 值和輪播圖高度的比值,這比值是會隨之 y值得變動而變動的, 那么我們就可以用這個來設置透明度,
需要注意的點是:
  • 要去掉 navigationBar 的底部陰影,這樣才不至于出現(xiàn)一條線,影響用戶體驗
  • 當tableView 拖到輪播圖下方時, navigationBar 要保持不透明顏色
  • 系統(tǒng)設置 navigationBar 時,默認的是半透明狀態(tài), 很不爽,所以需要生成一張純色圖,來動態(tài)地設置 navigationBar 的背景圖

那我們來開始一步步做吧

1. 首先,設置觀察者
#pragma mark *** 視圖的生命周期 ***
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
    
     /* tableViewController 觀察 tableView 的 contentOffset */
    [self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}
2. 當觀察者的觀察對象的屬性一發(fā)生變化時, 就調(diào)用這個方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if ([object isEqual:self.tableView] && [keyPath isEqualToString:@"contentOffset"]) {
        [self refreshNavigationBar];
    }
}
3.那么刷新 navigationBar-(void)refreshNavigationBar是個什么東西呢?
- (void)refreshNavigationBar
{
    CGPoint offset = self.tableView.contentOffset;
    
     /* 當 offset.y 值小于0時,狀態(tài)欄隱藏, 其余時候顯示 */
    self.navigationController.navigationBarHidden = (offset.y < 0);
    
     /* 在這個頁面中, 我的輪播圖的寬高比是180:300 */
     /* 那么我先算出輪播圖的高度 */
    CGFloat cycleScrollViewHeight = kScreenWidth * 180 / 300;
    
     /* 用 offset 值比上輪播圖的高度,那么,當輪播滾動范圍的 y 值等于輪播圖的高度時, navigationBar 就完全不透明了 */
    CGFloat alpha = MIN(1, fabs(offset.y / cycleScrollViewHeight));
    
     /* 設置 透明度為 NO 來消除 alpha 為1時的系統(tǒng)化透明 */
    
    BOOL translucent = !(int)alpha; /* 也就是說,當tableView 越往下拖, alpha 值為1,navigationBar 的透明度就始終保持不透明 */
    [self.navigationController.navigationBar setTranslucent:translucent];
    
     /* 設置實時的顏色 */
    UIColor *realTimeColor = [UIColor colorWithRed:0.14 green:0.79 blue:0.67 alpha:alpha];
     /* 用實時的顏色生成一張純色的圖片 */
    UIImage *image = [self navigationBarImageWithColor:realTimeColor];
    
    [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
     /* 消除陰影 */
    [self.navigationController.navigationBar setShadowImage:[UIImage new]];
    
}

第3步才是核心代碼, 很重要,

4.這里面還有一個重要的方法是生成一張純色圖,生成純色圖, 我們需要計算出純色圖的大小, 純色圖的大小實際上就是 navigationBar 的大小和狀態(tài)欄(statusBar 的大小)
- (UIImage *)navigationBarImageWithColor:(UIColor *)color
{
    CGSize navigationBarSize = self.navigationController.navigationBar.frame.size;
    CGSize statusBarSize = [[UIApplication sharedApplication]statusBarFrame].size;
    
    return [UIImage yf_imageWithPureColor:color size:CGSizeMake(navigationBarSize.width, navigationBarSize.height + statusBarSize.height)];
}
5.實際上真正生成純色圖的是這個方法:yf_imageWithPureColor:color size:

在這里,我們創(chuàng)造一個 UIImage 的分類,專門生成純色圖.這樣,我們在項目的其他任何地方需要根據(jù)顏色和大小生成純色圖的時候,都可以調(diào)用這個方法

創(chuàng)建一個生成純色圖的分類

分類方法的實現(xiàn)如下:

+ (UIImage *)yf_imageWithPureColor:(UIColor *)color size:(CGSize)size
{
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    [color set];
    UIRectFill(CGRectMake(0, 0, size.width, size.height));
    UIImage *renderImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return renderImage;
}
以上, 就是完成這個功能的全部步驟.

PS. 本人有若干成套學習視頻, 包含Java, 數(shù)據(jù)結構與算法, iOS, 安卓, python, flutter等等, 如有需要, 聯(lián)系微信tsaievan.

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

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

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