本文主要给大家介绍了关于利用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.jb51.net/201707/yuanma/ScrollCardDemo(jb51.net).rar
总结
以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
本文向大家介绍Android实现横向滑动卡片效果,包括了Android实现横向滑动卡片效果的使用技巧和注意事项,需要的朋友参考一下 最近项目上需要实现这样效果的一个页面,本来想找个现成的两下搞定,但是问了半天度娘也没招,索性自己琢磨琢磨(这里边也少不了同事的帮助),先把最终的效果图贴上: 理论上讲,其本质并不复杂,就是一个viewpager,但是第一次实现这样的效果还是要花些时间的,具体的代码如下
本文向大家介绍Android中实现水平滑动(横向滑动)ListView示例,包括了Android中实现水平滑动(横向滑动)ListView示例的使用技巧和注意事项,需要的朋友参考一下 水平的ListView-HorizontalListView的使用 Android中ListView默认的是竖直方向的滑动,由于项目的需求,需要ListView是水平滑动的。有很多的方式可以实现,但是比较好的一种方式
本文向大家介绍javascript图片滑动效果实现,包括了javascript图片滑动效果实现的使用技巧和注意事项,需要的朋友参考一下 本文为大家分享了javascript图片滑动效果实现方法,具体内容如下,先看一下效果图: 鼠标滑过那张图,显示完整的哪张图,移除则复位: 简单的CSS加JS操作DOM实现: css: js操作: 更多关于滑动效果的专题,请点击下方链接查看: javascript滑
本文向大家介绍Vue 实现从小到大的横向滑动效果详解,包括了Vue 实现从小到大的横向滑动效果详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Vue 实现从小到大的横向滑动效果。分享给大家供大家参考,具体如下: 最近项目中遇到一个需求,需要实现横向滑动,并且在滑动过程中,中间的大,两边的小,通过参考其他的人代码以及自己的实践,终于做出来啦,给大家做个参考。 实现效果如下图: 先来说一下
本文向大家介绍Android利用滑动菜单框架实现滑动菜单效果,包括了Android利用滑动菜单框架实现滑动菜单效果的使用技巧和注意事项,需要的朋友参考一下 之前我向大家介绍了史上最简单的滑动菜单的实现方式,相信大家都还记得。如果忘记了其中的实现原理或者还没看过的朋友,请先去看一遍之前的文章Android仿人人客户端滑动菜单的侧滑特效实现代码,史上最简单的侧滑实现 ,因为我们今天要实现的滑动菜单框架
本文向大家介绍AngularJS中实现动画效果的方法,包括了AngularJS中实现动画效果的方法的使用技巧和注意事项,需要的朋友参考一下 AngularJS 动画 AngularJS 提供了动画效果,可以配合 CSS 使用。 AngularJS 使用动画需要引入 angular-animate.min.js 库。 <script src="http://apps.bdimg.com/libs/a
本文向大家介绍Android实现探探图片滑动效果,包括了Android实现探探图片滑动效果的使用技巧和注意事项,需要的朋友参考一下 之前一段时间,在朋友的推荐下,玩了探探这一款软件,初玩的时候,就发现,这款软件与一般的社交软件如陌陌之类的大相径庭,让我耳目一新,特别是探探里关于图片滑动操作让人觉得非常新鲜。所以在下通过网上之前的前辈的经历加上自己的理解,也来涉涉水。下面是网上找的探探的原界面 当时
本文向大家介绍使用jQueryMobile实现滑动翻页效果的方法,包括了使用jQueryMobile实现滑动翻页效果的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了使用jQueryMobile实现滑动翻页效果的方法。分享给大家供大家参考。具体分析如下: 滑动手势在移动设备是很流行的,在移动设备中滑动翻页中很常见 虽然这个功能可以在jQueryMobile中实现,但是个人与之前一篇【j