美文网首页iOS开发技术iOS精选博文iOS超神之路
【导航条滚动透明】一个分类搞定

【导航条滚动透明】一个分类搞定

作者: HelloYeah | 来源:发表于2016-03-14 22:54 被阅读5222次
下面这个界面有没有觉得很眼熟。打开你手里的App仔细观察,你会发现很多都有实现这个功能。比如美团外卖的首页模块,新浪微博的个人详情页面。要怎么样才能快速的实现这个功能呢!那下面由笔者来告诉你如何三行代码,集成这个功能。。。
2.gif

原理介绍:

要想把一个view设计成透明的我们一下子就会想到两种方案,设置view的alpha值为0,或者设置view的backgroundColor为clearColor.但是UINavigationBar是一个比较特殊的视图,它是没有alpha属性的,那我们可以设置opaque(不透明度)为NO,上代码试一试

//方案一:不透明度为NO
navigationBar.opaque = NO;
//方案二:背景颜色为clearColor 
navigationBar.backgroudcolor = [UIColor clearColor];

结果,然并卵,完全没用。这时候该怎么办呢?这时候我们就得来看看UINavigationBar这个视图的结构了,如下图。

NavgationBar.png

现在笔者教大家一个小技巧。请看下面代码:

//设置一张空的图片
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
//清除边框,设置一张空的图片
[self.navigationController.navigationBar setShadowImage:[[UIImage alloc]init]];

这时候再打开项目层次图,你会有惊人的发现

Snip20160314_4.png

对比一下,你会发现只剩两层了。不要问为什么,这都是系统帮你做的。。。当你设置了背景图片的时候,就会出现这样的结果。

知道了上述的原理,这就好办了,现在只要监听,控制器内部的scrollView 的滚动,就可以实现导航条渐渐透明的效果了。

  • 业务逻辑,功能实现其实都不是很难。但是也需要花费一些时间,笔者在这给大家分享一下自己写的一个分类。导入这个分类,你只需要调用两三个接口就可以实现这个功能了。
    首先看一下分类提供的接口
Snip20160326_2.png

分类介绍

  • 我写的这个分类不仅可以在系统的UITableViewController 和UICollectionViewController中使用,(系统的只需调用分类中两个方法即可)。而且当你的UIViewController中有1个或多个可以垂直滚动的scrollView都可以使用。(需要告诉控制器需要监听哪个scrollView的滚动,即设置keyScrollView).
  • 重要的是,这个分类的代码侵入性非常低,使用简单方便。当不需要这些功能的时候,你只需要注释掉几行代码即可。对原控制器没有任何影响,无需更改控制器内的其他代码结构。

分类代码

分类接口
#import <UIKit/UIKit.h>
typedef struct {
    BOOL isLeftAlpha;
    BOOL isTitleAlpha;
    BOOL isRightAlpha;
    
}HYBarItemAlphaControl;
@interface UIViewController (NavBarHidden)
/** 当你的控制器里有多个scrollView的时候,设置需要监听的keyScrollView */
@property (nonatomic,weak) UIScrollView * keyScrollView;
/** 设置导航条上的标签是否需要跟着隐藏  */
- (void)setBarItemAlphaControl:(HYBarItemAlphaControl)isBarItemAlphaControl;
/**  
 *      在控制器ViewWillAppear.ViewWillDisappear需要调用的接口
 *      避免push到下一个控制器,消除对其他控制器导航条的影响
 */
- (void)setInViewWillAppear;
- (void)setInViewWillDisappear;
/** rate将决定颜色变化程度,值越大,颜色变化越明显,rate的取值范围是0.01 - 0.999999 */
- (void)scrollControlRate:(CGFloat)height colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue ;   
@end

下面这个效果图是系统的UITableViewController,以下是效果图和代码

2.gif

控制器代码:

#import "TestViewController.h"
#import "UIViewController+NavBarHidden.h"

@implementation TestViewController
- (void)viewDidLoad{
    [super viewDidLoad];
    //设置当有导航栏自动添加64的高度的属性为NO
    self.automaticallyAdjustsScrollViewInsets = NO;
    //设置tableView的头部视图
    UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 0, 250)];
    imageView.image = [UIImage imageNamed:@"1.jpg"];
    self.tableView.tableHeaderView = imageView;    
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
      [self scrollControlRate:0.5 colorWithRed:0.0 green:1.0 blue:0.0 ];
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self setInViewWillAppear];
}
- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self setInViewWillDisappear];
}
@end

下面这个效果图是一个ViewController中含有自己创建的一个CollectionView.

1.gif

控制器代码

@implementation TestCollectionController
-(void)viewDidLoad{ 
    [super viewDidLoad];
    //1.设置当有导航栏自动添加64的高度的属性为NO
    self.automaticallyAdjustsScrollViewInsets = NO;
    //2.设置导航条内容
    [self setUpNavBar];
    //3.导航条上的自定义的子标签是否需要跟着隐藏,只对自定义的view有效果.对系统默认的无效
    [self  setBarItemAlphaControl:(HYBarItemAlphaControl){0,1,1}];
    //4.设置collectionView
    [self setUpCollectionView];
    //5.告诉程序是根据哪个scrollView的滚动来控制状态栏的变化
    self.keyScrollView = self.collectionView;  
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
}

#warning 监听滚动,调用框架接口
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //rate将决定颜色变化程度,值越大,颜色变化越明显,rate的取值范围是0.01 - 0.999999
    [self scrollControlRate:0.5 colorWithRed:1.0 green:0.0 blue:0.0 ];   
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self setInViewWillAppear];
}
- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self setInViewWillDisappear];
}

项目源码分享,希望大家喜欢,下载的时候顺便star一下,好人多福。https://github.com/newyeliang/HYNavBarHidden.git

相关文章

网友评论

  • 11eddd582230:设置导航栏上的rightBarButtonItem的透明度不起作用
  • Damon___:调用之后pop回上一个界面之后就蹦掉了怎么回事?
  • sealife:git上面下载的为什么也是旧版本的...
  • sealife:大大,那个标题隐藏了,但push过去回来还是会显示。。。。
    HelloYeah:@sealife 不会啊
  • 来自南方的熊:源码跟你写的怎么不一样呢?你发表的这个有设置keyScrollVIew和颜色,rate这些啊,下载的源码没有这些?
    HelloYeah:源码更新了,看源码就好。
  • minjing_lin:楼主,[self doDeviceVersion] 这个在xcode8下,返回结果一直未0,offset一直为一个定值,屏幕的高。
    HelloYeah:@MinJing_Lin 嗯。用屏幕宽高判断挺好的。
    minjing_lin:@HelloYeah 哦哦,这样啊,直接用屏幕的高度来判断,不更好:smile:
    HelloYeah:@MinJing_Lin 你换真机调试。之前有网友反应,在iPhone5之前,runtime关联属性scrolOffsetY 会造成崩溃。所有做了[self doDeviceVersion] 判断。模拟器下[self doDeviceVersion] 返回结果为0
  • 上冬十二:楼主。。我引用了你的分类效果很好。就是push到下一个控制器的时候,也透明了。怎么解决呢。我本身就是用的自定义的导航控制器。。求救 :smiley:
    HelloYeah:能把你源码发给我看一下吗
    上冬十二:@HelloYeah 加了之后push过去的瞬间还是有零点几秒的半透明,之后恢复正常
    HelloYeah:@Pnyg_回眸 你push出来的控制器,再加个自定义的导航条
  • SAW_:那么问题来了,你第一张动图上,tableView的head,section置顶停留的效果却跑到了顶部去了,而不是停在导航栏的下面,这是一个很大的问题。
  • initial_J:我怎么从gitHub上down下来demo 直接运行,导航栏透明度没有变化而且,push 在pop回来崩溃
    initial_J:@HelloYeah 我再看下,谢谢回复
    HelloYeah:@initial_J 上周修改了代码,判断错了.现在已修复,你试试最新的代码
  • so_what:2.一定要push的话,那push出来的控制器最好使用自定义的导航条,自定义的导航条盖在最上面.

    这个怎么搞,特别是在处理系统手势侧滑返回那个动画,你gitHub上的demo没有体现出来,需要gif图片上的那种push效果,求指点,做好是更新demo,谢谢!
  • xxttw:给力啊.收藏了
  • STDawn:Mark
  • Joe_lisa: 确实不错,以前这个一直没有搞定
  • f7856ff03bec:rightBarButtonItem的push按钮用代码添加的话也隐掉了
    HelloYeah:@汉森可樂 嗯,源码更新了,简书内容还没更新!
    f7856ff03bec:@HelloYeah isLeftAlpha设置了,我等会再看看
    HelloYeah:有接口可以设置是否需要隐藏。
  • bcee5dd5dd26:牛Bility
  • 英秋Rachel:设置一个空图片的小技巧你是怎么想到的。。太机智了。。 我一直都是直接把导航栏hidden掉,然后自定义view :sweat:
    helloDolin:@英秋Rachel 观察图层,你会发现有很多方案
    英秋Rachel:@HelloYeah 👍👍👍
    HelloYeah:@英秋Rachel OC里有很多小技巧。多留意多思考就能发现
  • 葱花饼:这个把其它控制器的导航栏也隐藏了,还有左右2个按钮一拖也没有了
    葱花饼:你的意思是只拿到需要隐藏控制器的导航栏进行操作吗
    HelloYeah:@拥抱幸福 其他控制器被隐藏是因为,你说的其他控制器是被当前控制器push出来的,他们公用一个导条。要想有自己的样式,需要自己拿到导航条进行设置。
    HelloYeah:@拥抱幸福 如果左右按钮是自定义的,就能被隐藏。你可以看看源码

本文标题:【导航条滚动透明】一个分类搞定

本文链接:https://www.haomeiwen.com/subject/bczxlttx.html