接着上周的项目, 在上周我别出心裁的在自定义TabbarController中加入了自定义转场动画, 受到了大家广泛的喜爱, 再次表示感激, 今天我们继续实现LifestyleViewController的第二个功能渐变导航栏!!

渐变导航栏, 现在很多项目里都有这个功能, 我们就把这个功能集成到我们的项目中来; 根据设计图纸需求, 我们需要在轮播图下面有一个搜索栏, 搜索栏根据滑动偏移到导航栏之上.

具体怎么实现呢, Easy啦~ 不急,我们一步一步来.

创建搜索栏Cell

首先打开我们的项目先在轮播图Cell下创建一个搜索栏Cell 并添加子控件.

- (UIImageView *)hotSpotsImageView {

if (!_hotSpotsImageView) {

_hotSpotsImageView = [UIImageView new];

_hotSpotsImageView.image = [UIImage imageNamed:@"Hot Spots"];

}

return _hotSpotsImageView;

}

- (void)layoutSubviews {

[super layoutSubviews];

CGFloat padding = kSpace;

CGFloat hotSpotsImageViewX = padding;

CGFloat hotSpotsImageViewW = 90;

CGFloat hotSpotsImageViewH = 20;

CGFloat hotSpotsImageViewY = self.height - hotSpotsImageViewH - 5;

self.hotSpotsImageView.frame = CGRectMake(hotSpotsImageViewX, hotSpotsImageViewY, hotSpotsImageViewW, hotSpotsImageViewH);

}

这时你可能会问 为什么不在Cell中添加TextField之类的, 由于我们的效果,之后再向您揭晓;

控制器 多Cell设计

这时回到控制器, 但是控制器中不止一种Cell, 我们怎么来设计呢?? 我的实现方法是KeysArr, 那什么是KeysArr呢,我们来看代码.

首先我们需要创建一个全局类 (这个写法和上周的 投机流 自定义转场有异曲同工之妙)

创建全局类

全局类中的每一个Key对应着你的一个Cell

.h

extern NSString * const kSQLifestyleBannerKey;

extern NSString * const kSQLifestyleSearchKey;

.m

NSString * const kSQLifestyleBannerKey = @"轮播图";

NSString * const kSQLifestyleSearchKey = @"热点";

keys数组

接着我们创建一个数组来持有这些key;

@property (nonatomic,strong) NSArray * keysArr;

- (NSArray *)keysArr {

if (!_keysArr) {

_keysArr = @[kSQLifestyleBannerKey,

kSQLifestyleSearchKey];

}

return _keysArr;

}

Tableview delegate mothod

最后在代理方法中进行判断

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return self.keysArr.count;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

NSString * const key = self.keysArr[indexPath.row];

if (key == kSQLifestyleBannerKey) {

SQLifestyleBannerCell * cell = [SQLifestyleBannerCell cellWithTableView:tableView];

return cell;

}

if (key == kSQLifestyleSearchKey) {

SQLifestyleSearchCell * cell = [SQLifestyleSearchCell cellWithTableView:tableView];

return cell;

}

return nil;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

NSString * const key = self.keysArr[indexPath.row];

if (key == kSQLifestyleBannerKey) {

return [SQLifestyleBannerCell cellHeight];

}

if (key == kSQLifestyleSearchKey) {

return [SQLifestyleSearchCell cellHeight];

}

return 0;

}

这样当不需要某个cell显示的时候,只需要将keys从KeysArr中移除即可, 是不是很方便!!

创建搜索栏View

这里需要提醒大家的一点, 当你在自定义View的时候最好要实现initWithFrame和initWithCoder两个方法, 这样无论是用纯代码还是Xib,Storyboard使用自定义View时都能够直接加载!!

- (instancetype)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];

if (self) {

[self setupSubviews];

}

return self;

}

- (instancetype)initWithCoder:(NSCoder *)coder  {

self = [super initWithCoder:coder];

if (self) {

[self setupSubviews];

}

return self;

}

- (UITextField *)searchBarTextField {

if (!_searchBarTextField) {

_searchBarTextField = [UITextField new];

_searchBarTextField.backgroundColor = [UIColor whiteColor];

_searchBarTextField.layer.borderColor = KC05_dddddd.CGColor;

_searchBarTextField.layer.borderWidth = 0.5f;

_searchBarTextField.layer.cornerRadius = 5;

_searchBarTextField.layer.masksToBounds= YES;

_searchBarTextField.placeholder = @"Searching for something new";

_searchBarTextField.leftView = self.magnifierImageView;

_searchBarTextField.leftViewMode = UITextFieldViewModeAlways;

[_searchBarTextField setValue:KC04_999999 forKeyPath:@"placeholderLabel.textColor"];

}

return _searchBarTextField;

}

- (UIImageView *)magnifierImageView {

if (!_magnifierImageView) {

_magnifierImageView = [UIImageView new];

_magnifierImageView.image = [UIImage imageNamed:@"fa-search"];

_magnifierImageView.frame = CGRectMake(0, 0, 34, 34);

_magnifierImageView.contentMode = UIViewContentModeCenter;

}

return _magnifierImageView;

}

- (void)setupSubviews {

[self addSubview:self.searchBarTextField];

}

- (void)layoutSubviews {

[super layoutSubviews];

CGFloat searchBarTextFieldX = 0;

CGFloat searchBarTextFieldY = 0;

CGFloat searchBarTextFieldW = self.width;

CGFloat searchBarTextFieldH = 34;

self.searchBarTextField.frame = CGRectMake(searchBarTextFieldX, searchBarTextFieldY, searchBarTextFieldW, searchBarTextFieldH);

}

实现位移渐变

重于到今天的重头戏了, 我们来实现位移渐变!! 上面的自定义View 我们并不是将其添加到Cell之中, 而是将他添加到navigationController.view之上!!

创建两个自定义View

@property (nonatomic,strong) SQLifestyleSearchBarView * titleView;

@property (nonatomic,strong) SQLifestyleSearchBarView * searchBarView;

- (SQLifestyleSearchBarView *)titleView {

if (!_titleView) {

_titleView = [SQLifestyleSearchBarView new];

_titleView.frame = self.navigationController.navigationBar.frame;

}

return _titleView;

}

- (SQLifestyleSearchBarView *)searchBarView {

if (!_searchBarView) {

_searchBarView = [SQLifestyleSearchBarView new];

}

return _searchBarView;

}

其中一个的frame = self.navigationController.navigationBar.frame

并将其添加到titleView中!! 另一个将其加载navigationController.view中!! 并在viewWillLayoutSubviews中设置布局!!

- (void)loadView {

[super loadView];

[self.navigationItem setTitleView:self.titleView];

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor clearColor]] forBarMetrics:UIBarMetricsDefault];

[self.navigationController.navigationBar setShadowImage:[UIImage imageWithColor:[UIColor clearColor]]];

}

- (void)viewDidLoad {

[super viewDidLoad];

[self.view addSubview:self.tableView];

[self.navigationController.view addSubview:self.searchBarView];

}

- (void)viewWillLayoutSubviews {

[super viewWillLayoutSubviews];

CGFloat searchBarViewX = kSpace;

CGFloat searchBarViewW = self.titleView.width;

CGFloat searchBarViewH = self.titleView.height;

CGFloat searchBarViewY = kScaleLength(210) + searchBarViewH - self.tableView.contentOffset.y - searchBarViewH;

self.searchBarView.frame = CGRectMake(searchBarViewX, searchBarViewY, searchBarViewW, searchBarViewH);

}

监听偏移

我们将设置导航栏背景颜色的方法从LoadView移到scrollViewDidScroll中来

这里需要和大家细说一下监听偏移渐变,其实很简单,就是一个公式而已 float alpha = 1 - (offset) - scrollView.contentOffset.y) / offset); 其中的offset 指的是y轴方向从初始值viewWillLayoutSubviews中的初始设定 到导航栏的位移!!

每滑动下重新调用viewWillLayoutSubviews方法重新布局, 当其到达位移点的时候, 两个View进行交换就达到了 预期的效果!!

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

[self viewWillLayoutSubviews];

[[[UIApplication sharedApplication] keyWindow] endEditing:YES];

float alpha = 1 - ((kScaleLength(190.5) - scrollView.contentOffset.y) / kScaleLength(190.5));

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[KC01_57c2de colorWithAlphaComponent:alpha > 0.95f ? 0.95f : alpha]] forBarMetrics:UIBarMetricsDefault];

self.titleView.hidden = scrollView.contentOffset.y > kScaleLength(190.5) ? NO : YES;

self.searchBarView = !titleView.hidden;

}

对位移渐变的封装

上面的代码看到晕晕乎乎,讲的不清不楚!! 我们来讲这个功能封装一下, 先创建一个UIViewController的Catagory 实现方法!!

  • scrollView: 传入需要位移的scrollView;

  • titleView: 传入导航栏上的titleView;

  • movableView: 传入需要移动的自定义View;

  • offset: 传入y轴方向从初始值到导航栏的位移;

  • color: 传入导航栏颜色

- (void)navigationBarGradualChangeWithScrollView:(UIScrollView *)scrollView titleView:(UIView *)titleView movableView:(UIView *)movableView offset:(CGFloat)offset color:(UIColor *)color {

float alpha = 1 - ((offset - scrollView.contentOffset.y) / offset);

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[color colorWithAlphaComponent:alpha > 0.95f ? 0.95f : alpha]] forBarMetrics:UIBarMetricsDefault];

titleView  .hidden = scrollView.contentOffset.y > offset ? NO : YES;

movableView.hidden = !titleView  .hidden;

}

这样我们在调用的时候就简单明了多了!! 以后做到这个功能的时候可以直接拿来用了!!

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

[self viewWillLayoutSubviews];

[[[UIApplication sharedApplication] keyWindow] endEditing:YES];

[self navigationBarGradualChangeWithScrollView:scrollView titleView:self.titleView movableView:self.searchBarView offset:kScaleLength(190.5) color:KC01_57c2de];

}

模拟效果

为了能看到效果 我们在控制器中多加几个cell 方法很简单只要在Key数组中多加几个对象即可! 并在key == @"" 时加载如下Cell

- (NSArray *)keysArr {

if (!_keysArr) {

_keysArr = @[kSQLifestyleBannerKey,

kSQLifestyleSearchKey,

@"",@"",@"",@"",@"",

@"",@"",@"",@"",@"",

@"",@"",@"",@"",@"",

@"",@"",@"",@"",@""];

}

return _keysArr;

}

static NSString * identifier = @"cell";

UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];

if (!cell) {

cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];

}   cell.textLabel.text = @"https://coderZsq.github.io";

return cell;

好了 我们来看下显示效果吧~~

在Reaval中显示

最终显示

具体源码及SQExtension方法信息 请到github上进行下载! 喜欢的朋友送下小星星哟!!

https://github.com/coderZsq/coderZsq.project.ios

iOS 超 Easy 实现 渐变导航栏的更多相关文章

  1. iOS渐变导航栏封装

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

  2. 超详细Vue实现导航栏绑定内容锚点+滚动动画+vue-router(hash模式可用)

    超详细Vue实现导航栏绑定内容锚点+滚动动画+vue-router(hash模式可用) 转载自:https://www.jianshu.com/p/2ad8c8b5bf75 亲测有效~ <tem ...

  3. 【iOS开发-22】navigationBar导航栏,navigationItem建立:获取导航栏中的基本文本和button以及各种跳跃

    (1)navigationBar导航栏可以被看作是self.navigationController一个属性导航控制器,它可以由点直接表示self.navigationController.navig ...

  4. IOS开发之Bug--iOS7View被导航栏遮挡问题的解决

    在实际开发中,遇到在UITextView的frame等于当前控制器的View的frame的情况下,然后运行的时候,发现控制器的Frame的高度y值会从导航条的位置64变化到0. 导致UITextVie ...

  5. iOS开发笔记1:[转]导航栏里的"Back"按钮显示不出来

    最近项目中遇到一个问题,push过去的ViewController的Nav上面没有返回按钮,遂搜索资料,找到了以下文档.经测试i,问题解决. 原文地址:http://www.cnblogs.com/s ...

  6. iOS:自定义工具栏、导航栏、标签栏

    工具栏为UIToolBar,导航栏UINavigationBar,标签栏UITabBar.它们的样式基本上时差不多的,唯一的一点区别就是,工具栏一般需要自己去创建,然后添加到视图中,而导航栏和标签栏不 ...

  7. [iOS微博项目 - 1.2] - 导航栏搜索框

    A.导航栏搜索框 1.需求 在“发现”页面,在顶部导航栏NavigationBar上添加一个搜索框 左端带有“放大镜”图标 github: https://github.com/hellovoidwo ...

  8. iOS 删除黑色边框线导航栏&amp;删除搜索框的阴影边界线和中黑色文本输入框 - 解

    删除黑色边框线导航栏 in viewDidload: [self.navigationController.navigationBar setBackgroundImage:[[UIImage all ...

  9. iOS 要定义自己的导航栏button样式Button Image 执行出彩是不一样的与原来的颜色 -解

    在相机闪光灯,在导航栏中自己定义"闪"样式.点击变换的图像期望,但一直没有变化.原来是该条款的Global Tint颜色.因此,系统会自己主动改变图片的颜色Global Tint颜 ...

随机推荐

  1. 转】MyEclipse使用总结——MyEclipse10安装SVN插件

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/3497016.html 感谢! 一.下载SVN插件subclipse 下载地址:http://subclipse. ...

  2. hibernate search例子

    [TOC] 1. 概念介绍 1.1. Hibernate Search Hibernate Search是Hibernate的子项目,把数据库全文检索能力引入到项目中,并通过"透明" ...

  3. emWin显示文本字符-【worldsing笔记】

    在emWin显示文本字符还是容易的,提供了各种不同的接口,下面是有关于字符显示的常用的用法,可以直接复制到VS2008的模拟ucGui(emWin模拟工程)中运行: 工程代码下载:1.emWin5.2 ...

  4. windows server 2008 支持 .net framework 4.0

    windows server 2008平台下需要安装sp1,或打KB958854补丁,IIS7.0才能支持.net framework 4.0. 否则,IIS7.0中的应用程序虽然被配置为.net 4 ...

  5. 虚拟主机、VPS、云主机以及独立服务器的关系

    很多人对虚拟主机.VPS.云主机以及独立服务器的关系不是很了解,我在这里给大家简单分析一下. 先总结一下: (1)虚拟主机是把一台物理机器分割成很多的小空间,这些空间共享操作系统的资源,比如:同一个操 ...

  6. 当类库项目中无法使用Application.StartupPath

    通常我们WinForm编程时,要获取程序当前运行的文件夹路径会用Application.StartupPath ,但是Application.StartupPath在编写类库项目时却无法使用,因为我们 ...

  7. non-manifold Mesh(非流形网格)

    三角网格曲面中,大多的算法基于流形网格manifold mesh,其定义如下: 1)Each edge is incident to only one or two faces: 一条网格边为一个或两 ...

  8. OpenStack Hacker养成指南

    0 阅读指南 希望本文能够解开你心中萦绕已久的心结,假如是死结,请移步到 https://wiki.openstack.org/wiki/Main_Page 学习OpenStack其实就是学习各种Py ...

  9. 如何实现Conditional Include

    本文转载:http://www.cnblogs.com/brusehht/archive/2010/09/01/1814962.html 问题描述 有些朋友希望使用这样的一种查询方式,比如要查询Mov ...

  10. C语言综述

    1.预处理指令:在变异之前执行的指令. 系统自带的文件用<>,自己写的文件用""; .h成为头文件,用来声明一些常用的函数,假如想使用这些函数,就必须包含这个头文件(注 ...