iOS 動態修改導航欄顏色 UINavigationBar


示例

 所謂動態修改  意思是 在當前頁面滾動的過程中 亦或 是在 觸發返回事件\進入一個新的頁面  導航欄的動態變化

由於系統級別的navBar 高度集成  很多自己想實現的功能 很不好弄 如果是通過繼承的話,  參見 category 類別那章相對來說 更適用,自己開發一些個性自定義的方法去實現想要的功能. 

參見http://www.cocoachina.com/ios/20150409/11505.html

這篇文章 就是用類別的方法 拓展了 navigationBar 的實例方法 . 甚至動用了 c 底層. 不過 使用起來還是很方便 

上關鍵類別代碼

//

//  UINavigationBar+MyNavBar.h

//  LTNavigationBar

#import <UIKit/UIKit.h>

 @interface UINavigationBar (MyNavBar)

- (void)lt_setBackgroundColor:(UIColor *)backgroundColor;

- (void)lt_setElementsAlpha:(CGFloat)alpha;

- (void)lt_setTranslationY:(CGFloat)translationY;

- (void)lt_reset;

@end

//

//  UINavigationBar+Awesome.m

//  LTNavigationBar
#import "UINavigationBar+MyNavBar.h"

#import <objc/runtime.h>

 

@implementation UINavigationBar (MyNavBar)

static char overlayKey;

 

- (UIView *)overlay

{

    return objc_getAssociatedObject(self, &overlayKey);

}

 

- (void)setOverlay:(UIView *)overlay

{

    objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

 

- (void)lt_setBackgroundColor:(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;

}

 

- (void)lt_setTranslationY:(CGFloat)translationY

{

    self.transform = CGAffineTransformMakeTranslation(0, translationY);

}

 - (void)lt_setElementsAlpha:(CGFloat)alpha

{

    [[self valueForKey:@"_leftViews"] enumerateObjectsUsingBlock:^(UIView *view, NSUInteger i, BOOL *stop) {

        view.alpha = alpha;

    }];

    

    [[self valueForKey:@"_rightViews"] enumerateObjectsUsingBlock:^(UIView *view, NSUInteger i, BOOL *stop) {

        view.alpha = alpha;

    }];

    

    UIView *titleView = [self valueForKey:@"_titleView"];

    titleView.alpha = alpha;

//    when viewController first load, the titleView maybe nil

    [[self subviews] enumerateObjectsUsingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {

        if ([obj isKindOfClass:NSClassFromString(@"UINavigationItemView")]) {

            obj.alpha = alpha;

            *stop = YES;

        }

    }];

}

- (void)lt_reset

{

    [self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];

    [self.overlay removeFromSuperview];

    self.overlay = nil;

}

@end

 調用示例  這個效果 透明度的更改也是仿淘寶 展示 具體商品頁面的滑動效果  可以去查看

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.dataSource = self;
    [self.navigationController.navigationBar lt_setBackgroundColor:[UIColor clearColor]];
[self setBackButtonStyleLight:YES]; }
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { UIColor * color = [UIColor colorWithRed:0/255.0 green:175/255.0 blue:240/255.0 alpha:1]; CGFloat offsetY = scrollView.contentOffset.y; if (offsetY > NAVBAR_CHANGE_POINT) { CGFloat alpha = MIN(1, 1 - ((NAVBAR_CHANGE_POINT + 64 - offsetY) / 64)); // NAVBAR_CHANGE_POINT 和 64 這兩個參數 都是 看效果需求可酌情更改 就是 透明度變化的時機 系數 [self.navigationController.navigationBar lt_setBackgroundColor:[color colorWithAlphaComponent:alpha]];

         [self setBackButtonStyleLight:NO alpha:alpha];

    } else {
        [self.navigationController.navigationBar lt_setBackgroundColor:[color colorWithAlphaComponent:0]];

          [self setTitle:@""];

          [self setBackButtonStyleLight:YES];

    }
}

- (void)setBackButtonStyleLight:(BOOL)isLight
{
    [self setBackButtonStyleLight:isLight alpha:1];
}

- (void)setBackButtonStyleLight:(BOOL)isLight alpha:(CGFloat)alpha
{
    if(isLight){
        [titleLabel setAlpha:1];//導航標題
        [backButton setAlpha:1];//返回按鈕
        [titleLabel setText:@""];
        UIImage *image = backButton.imageView.image;
        UIImage *targetImage = [UIImage imageNamed:@"icon_fanhi"];
        if(image != targetImage){
            [backButton setImage:[UIImage imageNamed:@"icon_fanhi"] forState:UIControlStateNormal];
            [backButton setImage:[UIImage imageNamed:@"icon_fanhi"] forState:UIControlStateHighlighted];
        }
    }else{
        if(alpha < 0.5){
            [titleLabel setText:@""];
            UIImage *image = backButton.imageView.image;
            UIImage *targetImage = [UIImage imageNamed:@"icon_fanhi"];
            if(image != targetImage){
                [backButton setImage:[UIImage imageNamed:@"icon_fanhi"] forState:UIControlStateNormal];
                [backButton setImage:[UIImage imageNamed:@"icon_fanhi"] forState:UIControlStateHighlighted];
            }
            //先是之前的消失
            [backButton setAlpha:(0.5 - alpha) * 2];
        }else{
            UIImage *image = backButton.imageView.image;
            UIImage *targetImage = [UIImage imageNamed:@"icon_fanhihei"];
            if(image != targetImage){
                [backButton setImage:[UIImage imageNamed:@"icon_fanhihei"] forState:UIControlStateNormal];
                [backButton setImage:[UIImage imageNamed:@"icon_fanhihei"] forState:UIControlStateHighlighted];
            }
            [titleLabel setText:foodItemModel.foodName];
            //將返回和分享慢慢出現
            CGFloat showAlpha = (alpha - 0.5) * 2;
            [titleLabel setAlpha:showAlpha];
            [backButton setAlpha:showAlpha];
        }
    }
}
 
         

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:YES]; [self initScrollNav]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; //self.tableView.delegate = nil;//廢棄代碼 [self.navigationController.navigationBar lt_reset];//頁面消失時候要 恢復 正常導航欄模式 } - (void)initScrollNav { self.tableView.delegate = self; [self scrollViewDidScroll:self.tableView]; [self.tableView reloadData]; [self.navigationController.navigationBar setShadowImage:[UIImage new]]; } - (void)dealloc { self.tableView.delegate = nil;//不能在 viewWilldisappear 里nil 這時候 仍然會觸發 scrollViewDidLoad 導致崩潰 需要卸寫在這里 }

還有一種情況 就是滾動過程中 導航欄消失 保留狀態欄  這種情況 一些產品比較青睞  我個人特別不喜歡  一直堅信 ios7以后 蘋果就是倡導 狀態欄 導航欄一體化 所以留個狀態欄 你以為是安卓嗎? 丑爆了  然並卵  開發者只有提建議的權利 沒有決定權 怎么實現 還是要會的 是吧

示例:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offsetY = scrollView.contentOffset.y;
    if (offsetY > 0) {
        if (offsetY >= 44) {
            [self setNavigationBarTransformProgress:1];
        } else {
            [self setNavigationBarTransformProgress:(offsetY / 44)];
        }
    } else {
        [self setNavigationBarTransformProgress:0];
        self.navigationController.navigationBar.backIndicatorImage = [UIImage new];
    }
}

- (void)setNavigationBarTransformProgress:(CGFloat)progress
{
    [self.navigationController.navigationBar lt_setTranslationY:(-44 * progress)];
    [self.navigationController.navigationBar lt_setElementsAlpha:(1-progress)];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];//保留狀態欄的那種情況
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self.navigationController.navigationBar lt_reset];
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM