zoukankan      html  css  js  c++  java
  • 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];
    }
  • 相关阅读:
    iOS 关于字体根据不同屏幕尺寸等比适配的问题(zz)
    安卓开发:一种快速提取安卓app的UI图标资源的方法
    申请邓白氏编码的时候总是提示 Enter a valid Street Address 怎么办?
    利用日期、经纬度求日出日落时间 C语言程序代码(zz)
    JS导出Excel 代码笔记
    Bootstrap系列 -- 44. 分页导航
    Bootstrap系列 -- 43. 固定导航条
    Bootstrap系列 -- 42. 导航条中的按钮、文本和链接
    Bootstrap系列 -- 41. 带表单的导航条
    Bootstrap系列 -- 40. 导航条二级菜单
  • 原文地址:https://www.cnblogs.com/someonelikeyou/p/5124403.html
Copyright © 2011-2022 走看看