由于最近开发的几个项目都有渐变导航栏,每次写的时候都要copy一堆关于导航渐变相关的代码,显得类很冗余,所以花了点时间封装了一个渐变类,直接继承就可以满足大部分需求啦,这里简单写一下心路历程:

渐变的核心几个部分:

1.状态栏的变色:

添加一个状态栏属性BooL变量

@property(nonatomic,assign)BOOL lightStatusBar;//状态栏的颜色控制

我们可以在ViewController里面重写系统的这个方法来动态设置状态栏颜色(白色/黑色):
-(UIStatusBarStyle)preferredStatusBarStyle{
    return self.lightStatusBar ? UIStatusBarStyleLightContent : UIStatusBarStyleDefault;
}
如果需要主动的触发上面的方法改变状态栏颜色,我们可以直接调用这个方法 [self setNeedsStatusBarAppearanceUpdate];在ViewController写完上面两步,滑动导航栏会发现好像没什么卵用,状态栏颜色没变啊!

因为我们需要在UINavigationController里面重写下面这个方法-(UIViewController *)childViewControllerForStatusBarStyle;为什么要重写这个?这个方法默认返回值是nil,也就是当我们调用setNeedsStatusBarAppearanceUpdate的时候,系统会调用container(容器控制器)的preferredStatusBarStyle这个方法(app.window.rootViewController的preferred的方法,一般我们用UINavigationController或者UITabBarController来做container),也就是根本不会调用子控制器(我们所看到的UIViewcontroller)的preferredStatusBarStyle方法。这个时候- (UIViewController *)childViewControllerForStatusBarStyle:就派上用场了

给UINavigationController添加一个分类添加如下

重写这个方法,系统会调用container(容器控制器)就会返回当前的UIViewController,从而UIViewController里面重写的方法就会调用,状态栏的颜色就会相应改变。以上就是状态栏的变色出处理

2.导航栏的渐变

先做一下基础的设置:

1.禁止系统对继承Scrollview的控件的自动偏移

2.隐藏导航栏底部的线条,不处理的话导航栏透明时会明显看到一条黑线,辣眼睛。写个递归找到线条

调用上面方法找到线条图片,隐藏即可。

UIImageView *iamgeV = [self findBackLineImageV:self.navigationController.navigationBar];
    iamgeV.hidden = YES;

当我们滑动的时候会触发代理方法(必须要是继承Scrollview的控件设置代理才会触发):

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
}

在上面的方法我们主要做以下几件事情(把上面方法内容拆分说明一下):

1.滑动偏移量获取,通过滑动偏移量计算导航栏的透明度。

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    offset = scrollView.contentOffset.y;
    UIColor *color = [UIColor colorWithWhite:1.0 alpha:offset/self.offsetChange];
    [self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:color] forBarMetrics:UIBarMetricsDefault];
}

//绘制一张图片
- (UIImage *)imageWithColor:(UIColor *)color {
    CGSize size = CGSizeMake(1, 1);
    if (!color || size.width <= 0 || size.height <= 0) return nil;
    CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

2.滑动偏移量到设置的偏移量临界值时的处理(切换back图片,标题文字颜色,状态栏的bool值等)。

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

//导航栏渐变处理
    if (offset >= _offsetChange) {
        [self setBackNavNomal];
    }else{
        [self setBackNavDiaphanous];
    }
}

//不透明导航栏
-(void)setBackNavNomal
{
    self.navigationController.navigationBar.titleTextAttributes=@{NSForegroundColorAttributeName: self.notLucencyTitleColor,NSFontAttributeName:[UIFont systemFontOfSize:18]};
    [self setNavigationLeftItemWithImageName:@"more_dark"];
    [self.rightBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    self.lightStatusBar = NO;
}

//透明导航栏
-(void)setBackNavDiaphanous
{
    self.navigationController.navigationBar.titleTextAttributes= @{NSForegroundColorAttributeName: self.lucencyTitleColor,NSFontAttributeName:[UIFont systemFontOfSize:18]};
    [self setNavigationLeftItemWithImageName:@"navigationBack"];
     [self.rightBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    self.lightStatusBar = YES;
}

3.当tableview有组头并且组头要悬浮在导航栏下面,需要做的处理。

self.contentHeight为tableview的占屏大小,如果contentSize不用滑动就能显示完整,contentInset就不要修改,不然向上滑会有点bug。

self.offsetChange参数:没组头一般默认64就行,有组头则为组头到顶部的距离

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

if (self.tableView.contentSize.height >= self.contentHeight) {
        //导航栏渐变处理
        if (offset >= self.offsetChange) {
            self.tableView.contentInset = UIEdgeInsetsMake(KStatusBarAndNavigationBarHeight, 0, 0, 0);
        }else{
            self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
        }

}

}

整体-(void)scrollViewDidScroll:(UIScrollView *)scrollView 方法里面就是做上面三件事啦

做完这些就可以实现渐变了,项目中用的比较多的话直接继承设置一下参数就可以了。

demon地址:https://github.com/yizhixiafancai/ShadeViewController

iOS渐变导航栏封装的更多相关文章

  1. iOS 超 Easy 实现 渐变导航栏

    接着上周的项目, 在上周我别出心裁的在自定义TabbarController中加入了自定义转场动画, 受到了大家广泛的喜爱, 再次表示感激, 今天我们继续实现LifestyleViewControll ...

  2. IOS 改变导航栏返回按钮的标题

    IOS 改变导航栏返回按钮的标题   下午又找到了一个新的方法 这个方法不错 暂时没有发现异常的地方. 新写的App中需要使用UINavigationController对各个页面进行导航,但由于第一 ...

  3. iOS 11 导航栏 item 偏移问题 和 Swift 下 UIButton 设置 title、image 显示问题

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  4. iOS 自定义导航栏 和状态栏

    一.更改状态栏颜色 (StatusBar) 就是比如导航栏是红色的状态栏是绿色的. 要实现这样的效果其实很简单,就是添加一个背景view. 简单的实现过程如下: 1 // 设置导航颜色 可用 2 [s ...

  5. 【转】【iOS】导航栏那些事儿

    原文网址:http://www.jianshu.com/p/f797793d683f 参考文章 navigationItem UINavigationItem UINavigationBar UIBa ...

  6. iOS navigationBar导航栏底部与self.view的分界线的隐藏

    ios开发中经常碰到各种需求,比如要求导航栏的颜色和self.view的颜色一样,当我们直接设置navigationBar的颜色和view一样时,我们会发现navigationBar还会有一条分割线留 ...

  7. iOS项目导航栏返回按钮

    最近iOS项目中要求导航栏的返回按钮只保留那个箭头,去掉后边的文字,在网上查了一些资料,最简单且没有副作用的方法就是 [[UIBarButtonItem appearance] setBackButt ...

  8. 如何控制iOS的导航栏和状态栏的样式

    这是一个很常用的开发场景,就是改变导航栏上的文字颜色与背景色,如果你曾有 windows form 开发经验一定会笑我:"卧槽,这有什么好写的,不就是设置两个属性就可以了吗?" 我 ...

  9. iOS去除导航栏和tabbar的1px横线

    1.在自己定义的导航栏中或者设计稿中经常需要去除导航栏的1px横线,主要是颜色太不协调了 去除之前的图片 要去除这1px的横线,首先应该知道它是什么,在Xcode的界面调试中可以看到,它其实是UIIm ...

随机推荐

  1. Tab Key not working when using Xfce remote desktop

    Xfce 远程桌面Tab键设置 Use CTRL-tab instead of  tab The XFCE Terminal has kidnapped the tab key for a featu ...

  2. redis 迭代命令SCAN、SSCAN、HSCAN、ZSCAN

    SCAN 命令用于迭代当前数据库中的数据库键.SSCAN 命令用于迭代集合键中的元素.HSCAN 命令用于迭代哈希键中的键值对.ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值). S ...

  3. use ROW_NUMBER() for pagination in Oracle and SQLServer

    ------------------------------------------------------------------------Oracle---------------------- ...

  4. 短时傅里叶变换(Short Time Fourier Transform)原理及 Python 实现

    原理 短时傅里叶变换(Short Time Fourier Transform, STFT) 是一个用于语音信号处理的通用工具.它定义了一个非常有用的时间和频率分布类, 其指定了任意信号随时间和频率变 ...

  5. Paxos可容错的一致性协议

    一致性问题要求多个process对一个值达成一致.基于消息传递的分布式系统中,在不考虑消息篡改等拜占庭错误的情况下,Paxos可以解决在进程退出,消息延迟,丢失,重复等异常发生的环境中对某个值达成一致 ...

  6. springMVC入门-05

    接着上一讲,介绍如何查询单个数据,此处介绍show()方法的实现.显示单条数据需要使用Users对象中的一个字段作为入参来进行对象查询,将查询出来的数据放在Model中,并且将model中的user对 ...

  7. Jmeter入门--安装教程

    jmeter简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动 ...

  8. 审计系统---堡垒机python下ssh的使用

    堡垒机python下ssh的使用 [堡垒机更多参考]http://www.cnblogs.com/alex3714/articles/5286889.html [paramiko的Demo实例]htt ...

  9. windows 2012R2 上必须要用sharepoint 2013 sp1.

    已经确认. 虽然有人讲以下powershell可以帮助安装sharepoint 2013. 不过不是每次都可以的 Import-Module ServerManager Add-WindowsFeat ...

  10. 安装64位php开发环境

    最近听说PHP5.4速度很快,所以想建立一个本地环境测试下.我打算用本地windows xp sp3下安装PHP5.4.8.Apache2.4.3和Mysql5.5.28. 首先去下载PHP.Apac ...