實現collectionViewCell的移動(長按或者直接拖拽)

發表於2016-05-11

最近在實現類似網易新聞的首頁滑塊的編輯效果: 長按後進入編輯介面, 然後可以通過拖拽實現cell的移動, 研究後發現兩種實現方式: 第一種是直接利用系統提供的UICollectionView API實現移動, 不過只能在iOS9上面使用. 所以這裡就介紹另外一種方式.

原始碼效果示例:

實現collectionViewCell的移動(長按或者直接拖拽)

原理部分

  1. 新增一個長按手勢到UICollectionView上
  2. 在這個手勢的selector中通過獲取到當前手勢在collectionVIew的location來獲取到一個indexPath, 如果這個indexPath是有效的, 那麼就可以通過這個indexPath獲取到對應的cell.
  3. 將獲取到的cell截圖, 然後將這個cell隱藏, 通過設定這個截圖的frame使得這個截圖跟隨手指同步移動, 如果截圖移動到了另外一個cell的位置, 則通過呼叫collectionView的方法將這兩個cell交換位置, 同時需要更新collectionView的dataSource.

實現部分

  1. 在collectionView上新增一個長按手勢

2 在selector中處理手勢的響應

  • 2.1 獲取當前手勢的位置
  • 2.2 獲取這個位置對應的在collectionView中的indexPath, 注意這個indexPath可能為nil(比如手指沒有在cell的位置上時)
  • 2.3 通過當前手勢的狀態不同的處理

實現collectionViewCell的移動(長按或者直接拖拽)

遍歷狀態.png
  • 2.3.1 case .Began 手勢開始的時候

    a. 記錄下當前的indexPath以便於在手指移動的過程中進入.Changed狀態的時候使用
    b. 通過這個indexPath獲取到對應的cell
    c. 獲取到這個cell截圖
    d. 並且設定截圖的初始位置
    e. 隱藏當前的cell
    f. 將截圖新增到collectionView中
  • 2.3.2 case .Changed 手指在移動的時候

a. 如果在began狀態中沒有獲取到截圖直接返回
b. 設定截圖的位置, 以達到和手指同步移動
c. 如果新獲取到的indexPath有效並且和原來的不相同
d. 移動cell, 更新dataSource
e. 設定新的cell的屬性
f. 更新當前的indexPath

  • 2.3.3 case .End 手指離開螢幕的時候

a. 獲取到當前移動完成的cell
b. 使用動畫移除截圖並且設定當前的移動完成的cell的屬性

到目前位置, 設定好collectionView的datasource和delegate方法後就可以實現以下的效果了

實現collectionViewCell的移動(長按或者直接拖拽)


詳細請移步原始碼, 如果您覺得有幫助,不妨給個star鼓勵一下, 歡迎關注

相關文章