本文实例为大家分享了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的偏移量和中心点,进行一系列的计算:
解决最后一个小问题,拖动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 }最后一个方法不写看不到渐变的效果。
源码地址:点击打开链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。