實現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