iOS 超 Easy 实现 渐变导航栏

来源:Doubles_Z   

链接:http://www.jianshu.com/p/bba27212de69


接着上周的项目, 在上周我别出心裁的在自定义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_57c2decolorWithAlphaComponent: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 *)titleViewmovableView:(UIView *)movableView offset:(CGFloat)offset color:(UIColor *)color {

 

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

    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[colorcolorWithAlphaComponent: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.searchBarViewoffset: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;


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


由于微信限制 Gif 图大小,可到原文查看效果图


在Reaval中显示



最终显示



github 下载地址!!!



上周有人说我没有放出Demo 小弟真是冤枉至极, 这次特地做出标注

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

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


深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
【6层】4837.9平米六层框架综合办公楼(含计算书、建筑、结构图纸) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值