本文主要给大家介绍了关于利用swift实现卡片横向滑动动画效果的相关资料,分享出来供大家参考学习,下面来一起看看详细的介绍吧。

根据惯例,首先上效果图:
那天去面试,面试官突然拿出手机点开了一个app,自个在那点了一会,然后问我 这个效果怎么实现,当时一看可以滑动,肯定用scrollView 或者 collectionView实现,就大概的说了下。今天刚好闲下来,就敲一敲这个效果。
先来分析下这个效果:
卡片是横向滚动,并且每个卡片的位置都是保持在屏幕中间的,而且 左右相邻的卡片都露出来一点边
collectionView 和scrollView都可以实现,在这里,我们用collectionView实现,但是我们平常普通用的collectionView都是正屏滑动的!!而且是平滑,所有我们只能自定义UICollectionViewFlowLayout 流式布局,才可以达到上图效果.
废话不多说,直接上代码:
创建collectionView布局
//创建collectionView布局
func setepUI() {
//CustomLayout是自定义的UICollectionViewFlowLayout
layout = CustomLayout()
layout?.itemSize = CGSize(width: SCREEN_WIDTH-80, height: SCREEN_HEIGHT-64-120)
let rect = CGRect(x: 0, y: 64, width:SCREEN_WIDTH , height: SCREEN_HEIGHT-64)
collectionView = UICollectionView(frame: rect, collectionViewLayout: layout!)
collectionView?.delegate = self
collectionView?.dataSource = self
view.addSubview(collectionView!)
collectionView?.register(CustomViewCell.self, forCellWithReuseIdentifier: "identifier")
collectionView?.backgroundColor = UIColor.red
}
实现代理方法:
我们在extension中实现:
// MARK: -- delegate and datasource
extension ViewController:
UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout{
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//CustomViewCell是自定义的cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) as! CustomViewCell
cell.backgroundColor = UIColor.orange
cell.lable?.text = "\(indexPath.row)/\(10)"
return cell
}
}
至此,我们可以得到普通的效果,左右滑动,但中间cell不会居中,两侧cell也不会缩放,如下图:
这个时候就需要在自定义的流式布局 CustomLayout里做点什么了:
初始化方法 prepare , 初始化一些内容:
//重写prepare方法
//布局之前的准备工作 初始化 这个方法每次layout发生改变就调用一次
override func prepare() {
scrollDirection = UICollectionViewScrollDirection.horizontal
minimumLineSpacing = 20.0
sectionInset = UIEdgeInsets(top: 0, left: 40, bottom: 0, right: 40)
super.prepare()
}
(该方法默认返回false) 返回true frame发生改变就允许重新布局 内部会重新调用prepare 和
layoutAttributesForElementsInRect
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
MARK:---用来计算出rect这个范围内所有cell的UICollectionViewLayoutAttributes 对象,循环遍历每个attribute对象,修改frame,再将这数组返回给系统
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
//根据当前滚动进行对每个cell进行缩放
//首先获取 当前rect范围内的 attributes对象
let array = super.layoutAttributesForElements(in: rect)
private let ScaleFactor:CGFloat = 0.001//缩放因子
//计算缩放比 首先计算出整体中心点的X值 和每个cell的中心点X的值
//用着两个x值的差值 ,计算出绝对值
//colleciotnView中心点的值
let centerX = (collectionView?.contentOffset.x)! + (collectionView?.bounds.size.width)!/2
//循环遍历每个attributes对象 对每个对象进行缩放
for attr in array! {
//计算每个对象cell中心点的X值
let cell_centerX = attr.center.x
//计算两个中心点的便宜(距离)
//距离越大缩放比越小,距离小 缩放比越大,缩放比最大为1,即重合
let distance = abs(cell_centerX-centerX)
let scale:CGFloat = 1/(1+distance*ScaleFactor)
attr.transform3D = CATransform3DMakeScale(1.0, scale, 1.0)
}
return array
}
到目前为止,我们可以得到一个缩放的效果,但是仍然没有达到我们要的效果,可视区域的cell并没有居中显示,而是滑到哪里就到哪里:
如下图:
所以我们还得重写一个方法:
func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint
需要注意的两个参数:
实现该方法:
/// <#Description#>
///
/// - Parameter proposedContentOffset: 当手指滑动的时候 最终的停止的偏移量
/// - Returns: 返回最后停止后的点
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
let visibleX = proposedContentOffset.x
let visibleY = proposedContentOffset.y
let visibleW = collectionView?.bounds.size.width
let visibleH = collectionView?.bounds.size.height
//获取可视区域
let targetRect = CGRect(x: visibleX, y: visibleY, width: visibleW!, height: visibleH!)
//中心点的值
let centerX = proposedContentOffset.x + (collectionView?.bounds.size.width)!/2
//获取可视区域内的attributes对象
let attrArr = super.layoutAttributesForElements(in: targetRect)!
//如果第0个属性距离最小
var min_attr = attrArr[0]
for attributes in attrArr {
if (abs(attributes.center.x-centerX) < abs(min_attr.center.x-centerX)) {
min_attr = attributes
}
}
//计算出距离中心点 最小的那个cell 和整体中心点的偏移
let ofsetX = min_attr.center.x - centerX
return CGPoint(x: proposedContentOffset.x+ofsetX, y: proposedContentOffset.y)
}
至此,整个过程结束,其实很简单,主要是对这几个方法理解!
最后代码下载:
github下载地址:点这里
本地下载地址:http://xiazai./201707/yuanma/ScrollCardDemo().rar
总结
以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# swift
# 横向滑动卡片
# 横向滚动
# cell横向滚动图
# Swift使用CollectionView实现广告栏滑动效果
# 中心点
# 自定义
# 计算出
# 都是
# 遍历
# 我们可以
# 重写
# 越大
# 如下图
# 流式
# 在这里
# 点这里
# 偏移量
# 本地下载
# 下载地址
# 说了
# 那天
# 开了
# 问我
# 点了
相关文章:
建站三合一如何选?哪家性价比更高?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
建站之星2.7模板:企业网站建设与h5定制设计专题
一键制作网站软件下载安装,一键自动采集网页文档制作步骤?
如何选购建站域名与空间?自助平台全解析
网站专业制作公司有哪些,做一个公司网站要多少钱?
实现点击下箭头变上箭头来回切换的两种方法【推荐】
如何确保FTP站点访问权限与数据传输安全?
网站代码制作软件有哪些,如何生成自己网站的代码?
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
如何零基础在云服务器搭建WordPress站点?
定制建站流程解析:需求评估与SEO优化功能开发指南
如何选择CMS系统实现快速建站与SEO优化?
制作网站的公司有哪些,做一个公司网站要多少钱?
子杰智能建站系统|零代码开发与AI生成SEO优化指南
简单实现Android文件上传
网页设计与网站制作内容,怎样注册网站?
昆明网站制作哪家好,昆明公租房申请网上登录入口?
黑客如何利用漏洞与弱口令入侵网站服务器?
移民网站制作流程,怎么看加拿大移民官网?
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
Python多线程使用规范_线程安全解析【教程】
,怎么用自己头像做动态表情包?
我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?
如何通过cPanel快速搭建网站?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
如何快速搭建二级域名独立网站?
c++ stringstream用法详解_c++字符串与数字转换利器
如何通过主机屋免费建站教程十分钟搭建网站?
建站主机选哪家性价比最高?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
如何选择服务器才能高效搭建专属网站?
建站之星后台密码遗忘?如何快速找回?
制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?
c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
婚礼视频制作网站,学习*后期制作的网站有哪些?
青浦网站制作公司有哪些,苹果官网发货地是哪里?
建站之星在线客服如何快速接入解答?
中山网站推广排名,中山信息港登录入口?
香港服务器部署网站为何提示未备案?
如何通过虚拟主机空间快速建站?
SQL查询语句优化的实用方法总结
如何获取免费开源的自助建站系统源码?
广东专业制作网站有哪些,广东省能源集团有限公司官网?
网站制作服务平台,有什么网站可以发布本地服务信息?
C#怎么创建控制台应用 C# Console App项目创建方法
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
打鱼网站制作软件,波克捕鱼官方号怎么注册?
h5在线制作网站电脑版下载,h5网页制作软件?
*请认真填写需求信息,我们会在24小时内与您取得联系。