全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

iOS 页面滑动与标题切换颜色渐变的联动效果实例

话不多说,直接上图,要实现类似如下效果。

这个效果非常常见,这里着重讲讲核心代码

封装顶部的PageTitleView

封装构造函数

封装构造函数,让别人在创建对象时,就传入其实需要显示的内容 frame:创建对象时确定了

  1. frame就可以直接设置子控件的位置和尺寸
  2. isScrollEnable:是否可以滚动。某些地方该控件是可以滚动的。
  3. titles:显示的所有标题
// MARK:- 构造函数
init(frame: CGRect, isScrollEnable : Bool, titles : [String]) {
selfisScrollEnable = isScrollEnable
selftitles = titles
superinit(frame: frame)
}

设置UI界面

设置UI界面

  1.  添加UIScrollView,如果标题过多,则可以滚动
  2. 初始化所有的Label,用于显示标题。并且给label添加监听手势
  3. 添加顶部线和滑块的View

实现相对来说比较简单,这里代码从略

封装底部的PageCotentView

封装构造函数

封装构造函数,让别人在创建对象时,就传入其实需要显示的内容

  1. 所有用于显示在UICollectionView的Cell的所有控制器
  2. 控制器的父控制器
// MARK:- 构造函数
init(frame: CGRect, childVcs : [UIViewController], parentViewController : UIViewController) {
selfchildVcs = childVcs
selfparentViewController = parentViewController

superinit(frame: frame)
}

设置UI界面内容

设置UI界面

  1. 将所有的子控制器添加到父控制器中
  2. 添加UICollectionView,用于展示内容
// MARK:- 懒加载属性
private lazy var collectionView : UICollectionView = {
// 1.创建布局
let layout = UICollectionViewFlowLayout()
layout.itemSize = self.bounds.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .Horizontal
// 2.创建collectionView
let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
collectionView.showsHorizontalScrollIndicator = false
collectionView.pagingEnabled = true
collectionView.bounces = false
collectionView.scrollsToTop = false
collectionView.dataSource = self
collectionView.delegate = self
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: kContentCellID)
return collectionView
}()
private func setupUI() {
// 1.添加所有的控制器
for childVc in childVcs {
parentViewController?.addChildViewController(childVc)
}
// 2.添加collectionView
addSubview(collectionView)
}

实现UICollectionView的数据源方法

  1. 在返回Cell的方法中,先将cell的contentView中的子控件都移除,防止循环引用
  2. 取出indexPath.item对应的控制器,将控制器的View添加到Cell的contentView中
// MARK:- 遵守UICollectionView的数据源
extension PageContentView : UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return childVcs.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(kContentCellID, forIndexPath: indexPath)
// 移除之前的
for subview in cell.contentView.subviews {
subview.removeFromSuperview()
}
// 取出控制器
let childVc = childVcs[indexPath.item]
childVc.view.frame = cell.contentView.bounds
cell.contentView.addSubview(childVc.view)
return cell
}
}

PageTitleView点击改变PageContentView

通过代理将PageTitleView的事件传递出去

/// 定义协议
protocol PageTitleViewDelegate : class {
func pageTitleView(pageTitleView : PageTitleView, didSelectedIndex index : Int)
}
@objc private func titleLabelClick(tapGes : UITapGestureRecognizer) {
// 1.获取点击的下标志
guard let view = tapGes.view else { return }
let index = view.tag
// 2.滚到正确的位置
scrollToIndex(index)
// 3.通知代理
delegate?.pageTitleView(self, didSelectedIndex: index)
}

内部调整

// 内容滚动
private func scrollToIndex(index : Int) {
// 1.获取最新的label和之前的label
let newLabel = titleLabels[index]
let oldLabel = titleLabels[currentIndex]
// 2.设置label的颜色
newLabel.textColor = kSelectTitleColor
oldLabel.textColor = kNormalTitleColor
// 3.scrollLine滚到正确的位置
let scrollLineEndX = scrollLine.frame.width * CGFloat(index)
UIView.animateWithDuration(0.15) {
self.scrollLine.frame.origin.x = scrollLineEndX
}
// 4.记录index
currentIndex = index
}

在PageContentView中设置当前应该滚动的位置

// MARK:- 对外暴露方法
extension PageContentView {
 func scrollToIndex(index : Int) {
let offset = CGPoint(x: CGFloat(index) * collectionViewboundswidth, y: 0)
 collectionViewsetContentOffset(offset, animated: false)
}
}

PageContentView滚动调整PageTitleView

通过观察,我们发现:

                1> 原来位置的Title颜色会逐渐变暗

                2> 目标位置的Title颜色会逐渐变亮

                3> 变化程度是和滚动的多少相关

由此得出结论:

我们一共需要获取三个值

1> 起始位置下标值

2> 目标位置下标值

3> 当前滚动的进度

其实前2点可以由第3点计算而来,可以只需要将进度传递出去。

根据进度值处理标题颜色渐变及滑块逻辑

         。当前进度值唯一确定了标题的状态,计算出需要发生颜色变化的两相邻标题索引

         。注意:下标值需要防止越界问题,临界点的处理

实现代码

extension PageContentView : UICollectionViewDelegate {

func scrollViewWillBeginDragging(scrollView: UIScrollView) {

startOffsetX = scrollView.contentOffset.x

}

func scrollViewDidScroll(scrollView: UIScrollView) {

// 0.判断是否是点击事件

 if isForbidScrollDelegate { return }

// 1.定义获取需要的数据

 var progress : CGFloat = 0

 let currentOffsetX = scrollView.contentOffset.x

 let scrollViewW = scrollView.bounds.width

  // 1.计算progress

  progress = currentOffsetX / scrollViewW

  // 3.将progress传递给titleView

 delegate?.pageContentView(self, progress: progress)

 }

}

根据滚动传入的值,调整PageTitleView

两种颜色必须使用RGB值设置(方便通过RGB实现渐变效果)

private let kNormalRGB : (CGFloat, CGFloat, CGFloat) = (85, 85, 85)

private let kSelectRGB : (CGFloat, CGFloat, CGFloat) = (255, 128, 0)

private let kDeltaRGB = (kSelectRGB.0 - kNormalRGB.0, kSelectRGB.1 - kNormalRGB.1, kSelectRGB.2 - kNormalRGB.2)

private let kNormalTitleColor = UIColor(red: 85/255.0, green: 85/255.0, blue: 85/255.0, alpha: 1.0)

private let kSelectTitleColor = UIColor(red: 255.0/255.0, green: 128/255.0, blue: 0/255.0, alpha: 1.0)

调整scrollLine及两个Label颜色渐变

// MARK:- 对外暴露方法

extension PageTitleView

 func changeLabel(progress: CGFloat) {

// 开启弹簧效果时的过滤处理
 var progress = progress > 0 ? progress : 0

  progress = progress <= CGFloat(titleLabels.count - 1) ? progress : CGFloat(titleLabels.count - 1)

 var leftLabelIndex = Int(floor(progress))

 let ratio = progress - CGFloat(leftLabelIndex)

 //获取leftLabel和rightLabel

 let leftLabel = titleLabels[leftLabelIndex]

 if leftLabelIndex >= 3{

  leftLabelIndex = 3

 }

 print("leftLabelIndex = \(leftLabelIndex)")

 var rightIndex = leftLabelIndex + 1

 if rightIndex >= 3{

  rightIndex = 3

 }

 print("rightIndex = \(rightIndex)")

 let rightLabel = titleLabels[rightIndex]

 //滑块的逻辑

 let moveTotalX = leftLabel.frame.width

 let moveX = moveTotalX * ratio

 scrollLine.frame.origin.x = leftLabel.frame.origin.x + moveX

 //3.Label颜色的渐变

 // 3.1.取出变化的范围

 let colorDelta = (kSelectedColor.0 - kNormalColor.0, kSelectedColor.1 - kNormalColor.1, kSelectedColor.2 - kNormalColor.2)

 if leftLabelIndex != rightIndex {

 // 3.2.变化leftLabel

 leftLabel.textColor = UIColor(r: kSelectedColor.0 - colorDelta.0 * ratio, g: kSelectedColor.1 - colorDelta.1 * ratio, b: kSelectedColor.2 - colorDelta.2 * ratio)

 // 3.2.变化rightLabel

 rightLabel.textColor = UIColor(r: kNormalColor.0 + colorDelta.0 * ratio, g: kNormalColor.1 + colorDelta.1 * ratio, b: kNormalColor.2 + colorDelta.2 * ratio)

 }

 // 4.记录最新的index

 currentIndex = leftLabelIndex
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# ios  # 导航栏滑动渐变  # 标题栏渐变  # iOS Segment带滑动条切换效果  # iOS使用pageViewController实现多视图滑动切换  # 浅析iOS多视图滑动点击切换的集成  # iOS Objective-c实现左右滑动切换页面  # 滑块  # 移除  # 确定了  # 两种  # 而来  # 只需  # 要将  # 则可  # 多说  # 先将  # 大家多多  # 计算出  # 就可以  # 上图  # 判断是否  # 器中  # 加载  # 变暗  # 变亮  # collectionViewLayout 


相关文章: 如何选择CMS系统实现快速建站与SEO优化?  建站之星好吗?新手能否轻松上手建站?  Swift中switch语句区间和元组模式匹配  专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?  如何解决VPS建站LNMP环境配置常见问题?  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  怎么将XML数据可视化 D3.js加载XML  如何快速搭建高效WAP手机网站?  如何在云指建站中生成FTP站点?  如何在橙子建站中快速调整背景颜色?  建站之星在线版空间:自助建站+智能模板一键生成方案  建站之星微信建站一键生成小程序+多端营销系统  如何制作算命网站,怎么注册算命网站?  高端建站如何打造兼具美学与转化的品牌官网?  Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解  浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?  网站制作新手教程,新手建设一个网站需要注意些什么?  Python如何创建带属性的XML节点  C#怎么创建控制台应用 C# Console App项目创建方法  建站之星北京办公室:智能建站系统与小程序生成方案解析  如何通过智能用户系统一键生成高效建站方案?  焦点电影公司作品,电影焦点结局是什么?  建站org新手必看:2024最新搭建流程与模板选择技巧  内部网站制作流程,如何建立公司内部网站?  c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】  深圳网站制作的公司有哪些,dido官方网站?  如何通过虚拟主机空间快速建站?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?  建站VPS推荐:2025年高性能服务器配置指南  如何快速查询域名建站关键信息?  建站与域名管理如何高效结合?  如何在Windows虚拟主机上快速搭建网站?  制作营销网站公司,淘特是干什么用的?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  建站之星价格显示格式升级,你的预算足够吗?  建站之星导航菜单设置与功能模块配置全攻略  C++如何使用std::optional?(处理可选值)  如何快速生成橙子建站落地页链接?  北京专业网站制作设计师招聘,北京白云观官方网站?  建站之星收费标准详解:套餐费用及年费价格表一览  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  完全自定义免费建站平台:主题模板在线生成一站式服务  长沙做网站要多少钱,长沙国安网络怎么样?  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  如何选择适合PHP云建站的开源框架?  详解jQuery中基本的动画方法  大连网站设计制作招聘信息,大连投诉网站有哪些? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。