[英]How to make paging animation for a collectionView cell scrolling to center?
我正在使用swift 3編寫具有UIViewController
的應用程序,如下圖所示。 它的頂部包含一個可水平滾動的collectionView
(藍色方框),其功能是在不同的標簽之間切換(第一,上一個,當前,下一個,最后...等,總標簽數量不固定)。 我需要實現的是,在滾動(或平移)集合視圖時, “ NEXT”或“ PREV”應以類似於分頁動畫的速度移動(並自動錨定)到中心。 我怎樣才能做到這一點? 當前,我使用scrollView
的Paging Enabled
屬性,但是僅在窗口中有一個標簽時才有效。
類似的功能可能看起來像iTunes應用程序的中間“相冊”部分,一旦它檢測到任何滑動/平移手勢,collectionView單元格就會隨着某些動畫自動滾動到一些預定義的點。
根據您的評論,如果您想執行Tap來選擇事物,則需要做2件事
1-禁用viewDidLoad中的集合視圖滾動
collectionView.isScrollingEnabled = false
2-在中心顯示選定的單元格,將其添加到didSelectItemAtIndexPath方法中
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collection.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizantally)
let cell = collectionView.cellForItem(at : indexPath) as! YourCollectionViewCellClass
cell.titleLable.font = UIFont.boldSystemFont(ofSize : 20)
}
感謝Raheel 在這里的回答,我終於找到了一種理想的滾動效果的方法。 快速列出了一些關鍵功能:
scrollView
Paging Enabled
屬性 定義setIdentityLayout()
和setNonIdentityLayout()
,它們定義選定/未選定單元格的布局(例如,本例中為MyCollectionViewCell
)
定義一些相關屬性,例如:
lazy var COLLECTION_VIEW_WIDTH: CGFloat = { return CGFloat(self.collectionView.frame.size.width / 2) }() fileprivate let TRANSFORM_CELL_VALUE = CGAffineTransform(scaleX: 1, y: 1) // Or define other transform effects here fileprivate let ANIMATION_SPEED = 0.2
為UIScrollViewDelegate
實現以下關鍵方法:
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { // Do tableView data refresh according to the corresponding pages here } func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { // Scroll to corresponding position let pageWidth: Float = Float(COLLECTION_VIEW_WIDTH) // width + space let currentOffset: Float = Float(scrollView.contentOffset.x) let targetOffset: Float = Float(targetContentOffset.pointee.x) var newTargetOffset: Float = 0 if targetOffset > currentOffset { newTargetOffset = ceilf(currentOffset / pageWidth) * pageWidth } else { newTargetOffset = floorf(currentOffset / pageWidth) * pageWidth } if newTargetOffset < 0 { newTargetOffset = 0 } else if (newTargetOffset > Float(scrollView.contentSize.width)){ newTargetOffset = Float(Float(scrollView.contentSize.width)) } targetContentOffset.pointee.x = CGFloat(currentOffset) scrollView.setContentOffset(CGPoint(x: CGFloat(newTargetOffset), y: scrollView.contentOffset.y), animated: true) // Set transforms let identityIndex: Int = Int(newTargetOffset / pageWidth) var cell = delegate!.roomCollections.cellForItem(at: IndexPath.init(row: identityIndex, section: 0)) as? MyCollectionViewCell UIView.animate(withDuration: ANIMATION_SPEED, animations: { cell?.transform = CGAffineTransform.identity cell?.setIdentityLayout() }) // right cell cell = delegate!.roomCollections.cellForItem(at: IndexPath.init(row: identityIndex + 1, section: 0)) as? MyCollectionViewCell UIView.animate(withDuration: ANIMATION_SPEED, animations: { cell?.transform = self.TRANSFORM_CELL_VALUE cell?.setNonIdentityLayout() }) // left cell, which is not necessary at index 0 if (identityIndex != 0) { cell = delegate!.roomCollections.cellForItem(at: IndexPath.init(row: identityIndex - 1, section: 0)) as? MyCollectionViewCell UIView.animate(withDuration: ANIMATION_SPEED, animations: { cell?.transform = self.TRANSFORM_CELL_VALUE cell?.setNonIdentityLayout() }) } }
最后,在func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
定義初始布局:
if (indexPath.row == 0 && /* other first item selected condition */) { cell.setIdentityLayout() } else { cell.transform = TRANSFORM_CELL_VALUE cell.setNonIdentityLayout() }
要添加觸摸滾動效果,只需將target添加到每個集合視圖中,並進行類似的計算即可更改scrollView
的contentOffSet,此處將其省略,因為此功能更簡單而不是主要問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.