实现UICollectionView的自动滚动,以及一屏下,中间显示一个view,两边显示半个view的效果,
如图:git
自动滚动是使用Timer实现,每一个一段时间让UICollectionView自动滚动下便可。github
//自动滚动计时器 var autoScrollTimer:Timer?
var index: Int = 0
func startTimer() { //设置一个定时器,每三秒钟滚动一次 autoScrollTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(UICollectionViewTypeOneController.scroll), userInfo: nil, repeats: true) }
定时器没3秒响应scroll方法一次
//计时器时间一到,滚动一张图片 @objc func scroll(){ index = index + 1 index = index >= dataCollection.count ? 0 : index collectionView.scrollToItem(at: IndexPath.init(row: index, section: 0), at: .centeredHorizontally, animated: true) }
index 是下标,因此当index和数据源的大小一致时,就把index重置为0,不然就加一,scrollToItem方法是UICollectionView的自带方法,实现滚动效果。
核心思想是实现UICollectionViewFlowLayout的prepare()和targetContentOffset方法
class ProductAHorCollectionViewFlowLayout: UICollectionViewFlowLayout { override func prepare() { super.prepare() } override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { } }
prepare方法咱们作一些初始化操做,如设置Item的大小和左右边距等ide
let left = (self.collectionView!.bounds.width - itemWidth) / 2 let top = (self.collectionView!.bounds.height - itemHeight) / 2 self.sectionInset = UIEdgeInsetsMake(top, left, top, left)
left 保证第一个和最后一个ItemView会居中显示
top 保证只显示一行。
至此咱们已经实现了一个view居中显示,两边显示个头的效果,可是由于咱们要保证,用户滑动结束后,中间的view一直显示在中间,因此要实现下targetContentOffset方法。spa
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { //中止滚动时的可见区域 let lastRect = CGRect(x: proposedContentOffset.x, y: proposedContentOffset.y, width: self.collectionView!.bounds.width, height: self.collectionView!.bounds.height) //当前屏幕中点,相对于collect view上的x坐标 let centerX = proposedContentOffset.x + self.collectionView!.bounds.width * 0.5; //这个可见区域内全部的单元格属性 let array = self.layoutAttributesForElements(in: lastRect) //须要移动的距离 var adjustOffsetX = CGFloat(MAXFLOAT); for attri in array! { //每一个单元格里中点的偏移量 let deviation = attri.center.x - centerX //保存偏移最小的那个 if abs(deviation) < abs(adjustOffsetX) { adjustOffsetX = deviation } } //经过偏移量返回最终停留的位置 return CGPoint(x: proposedContentOffset.x + adjustOffsetX, y: proposedContentOffset.y) }
原理就是计算出每个view 的偏移量,得到最小偏移量的那个,本来停留的的位置 + 最小偏移量,就是一个view的居中位置。Git:https://github.com/LSnumber1/...code