Swift实现3D轮播图效果
本文实例为大家分享了Swift实现3D轮播图效果的具体代码,供大家参考,具体内容如下
整天逛淘宝,偶尔有一天看到其中的展示页有个看起来很炫的效果,闲来无事就试着写一个出来,先来看效果:
简单记一下思路,这里我选择使用UICollectionView控件,先根据其复用和滚动的特性做出无限轮播的效果,关键代码:
//数据源数组 let totalCount = 100 var models: [String] = [String]() { didSet { //判断元素个数 if models.count < 2 { collectionView.isScrollEnabled = false } //网上的找来的一个办法添加100组数据源对应的索引数组indexArr for _ in 0..<totalCount { for j in 0..<models.count { indexArr.append(j) } } //开始就滚动到第50组数据源 collectionView.scrollToItem(at: IndexPath(item: totalCount/2 * models.count, section: 0), at: .centeredHorizontally, animated: false) } }
滚动停止时走的方法里做处理:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { //找到滚动停止的点对应的collectionView的indexPath let point = self.convert(collectionView.center, to: collectionView) let index = collectionView.indexPathForItem(at: point) let indexpath = (index?.row ?? 0) % models.count collectionView.scrollToItem(at: IndexPath(item: totalCount/2 * models.count + indexpath, section: 0), at: .centeredHorizontally, animated: false) }
以上是滚动的处理,接下来就是item的渐变效果处理,看到这种情况就想到要写一个UICollectionViewFlowLayout
类供collectionView使用,UICollectionViewFlowLayout是管理item怎么展示用的,首先重写展示视图内的layoutAttributes方法,在此方法中找到attribute对应的item及其属性,和collectionView的偏移量和中心点,进行一系列的计算:
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { //集合视图的宽高(这里默认宽高相等) let itemHeight = self.collectionView?.frame.height ?? 0 //可是视图内的attributes数组 let array = super.layoutAttributesForElements(in: rect) //item透明度开始变化时的item的中心点x let centerX = self.collectionView!.contentOffset.x + itemHeight/2 print(self.collectionView?.contentOffset.x ?? 0) for attributes in array! { //开始变化时的item的中心点x 与 实际中心点相比较 let value = attributes.center.x - centerX let delta = abs(value) //设置缩放比例,此处4*itemHeight可根据缩放效果进行修改 let scale = 1 - delta/(4*itemHeight) //设置缩放比例 attributes.transform = CGAffineTransform.init(scaleX: scale, y: scale) //层次关系,设置此属性使item依次上下排列 attributes.zIndex = Int(1 - abs(delta)) //value<=0表示向左移动,最前面的item停止一段距离 if value <= 0{ //实际中心点与开始变化时的item的中心点小于等于设定的边界值 if delta >= 0 && delta <= itemHeight { //item的中心点固定不变 attributes.center.x = centerX //根据推进值,改变item的透明度,此处的delta>10是想让item有一个达到目标区域时有一个停顿效果而不是直接进入改变透明度的阶段 attributes.alpha = (delta > 10) ? (1 - delta/(itemHeight/4)) : 1 //设置缩放比例,停顿阶段不进行缩放 attributes.transform = CGAffineTransform.init(scaleX: 1, y: 1) } else { //移动大于边界值,就是从停顿阶段到透明度改变,此处是下一个item上来,当前item透明度变为0 attributes.alpha = 0 } } } return array }
解决最后一个小问题,拖动iitem开始滚动,滚动结束时让它自动滚动到网格区域,而不是停在当前或许不适当的地方,重写UICollectionViewFlowLayout另一个方法:
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { let targetRect = CGRect(x: proposedContentOffset.x, y: 0.0, width: self.collectionView!.bounds.size.width, height: self.collectionView!.bounds.size.height) //目标区域中包含的cell let attrArray = super.layoutAttributesForElements(in: targetRect) as! [UICollectionViewLayoutAttributes] //collectionView落在屏幕重点的x坐标 let horizontalCenterX = proposedContentOffset.x + (self.collectionView?.frame.height ?? 0)/2 var offsetAdjustment = CGFloat(MAXFLOAT) for layoutAttributes in attrArray { let itemHorizontalCenterX = layoutAttributes.center.x //找出离中心店最近的 if (abs(itemHorizontalCenterX-horizontalCenterX) < abs(offsetAdjustment)) { offsetAdjustment = itemHorizontalCenterX - horizontalCenterX } } //返回collectionView最终停留的位置 return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y) } //当collectionView的显示范围发生改变的时候,是否重新布局 override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true }
最后一个方法不写看不到渐变的效果。
源码地址:点击打开链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要介绍了如何使用JavaScript实现“无缝滚动 自动播放”轮播图效果,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-20
- 这篇文章主要给大家介绍了关于swift中利用runtime交换方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。...2020-06-30
- 这篇文章主要为大家详细介绍了vue+rem自定义轮播图效果,手指触摸左滑和右滑,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-06-29
- 有时候,我们需要一个显示文字,又想这些文字与边界之间有自定义的边距,所以下面这篇文章主要给大家介绍了关于Swift设置UILabel内边距的相关资料,需要的朋友可以参考下...2021-10-14
- 这篇文章主要给大家介绍了关于swift中@UIApplicationMain的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。...2020-06-30
- 这篇文章主要为大家详细介绍了Swift实现多个TableView侧滑与切换效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-30
- 给大家详细讲解了IOS开发中swift语言xcworkspace多项目管理的方法和介绍,一起参考一下。...2020-06-30
- 这篇文章主要为大家详细介绍了JS轮播图的实现方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-25
Swift 中如何使用 Option Pattern 改善可选项的 API 设计
这篇文章主要介绍了Swift 中如何使用 Option Pattern 改善可选项的 API 设计,帮助大家更好的进行ios开发,感兴趣的朋友可以了解下...2020-10-23- 这篇文章主要介绍了如何使用Swift来实现一个命令行工具,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-30
- 这篇文章主要给大家介绍了关于Swift中命名空间的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-30
- 这篇文章主要为大家详细介绍了基于jquery实现轮播图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-03-14
浅析Swift中struct与class的区别(汇编角度底层分析)
这篇文章主要介绍了Swift中struct与class的区别 ,本文从汇编角度分析struct与class的区别,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-30- 最近有一个需求,就是将图片先等比例缩放到指定大小,然后将空余出来空间填充为黑色,返回指定大小的图片。本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2021-11-02
- 这篇文章主要给大家介绍了关于Swift中优雅的处理闭包导致的循环引用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Swift具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-30
- 这篇文章主要为大家详细介绍了使用jquery实现轮播图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-01-02
- 这篇文章主要为大家详细介绍了Swift实现倒计时5秒功能,在“登录”和“注册”页面也有相似功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-30
- 这篇文章主要介绍了Swift 使用 Observe 监测页面滚动的实现方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-30
- 这篇文章主要介绍了Swift在控件中添加点击手势的方法,本文讲解如何在tableview的headerview中添加点击手势的方法,需要的朋友可以参考下...2020-06-30
- 有很多地方会用到类型擦除,并且它们的作用的各不相同。下面这篇文章主要给大家介绍了关于Swift如何使用类型擦除及自定义的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2020-06-30