【譯】UICollectionView 輕松重排

VernitaDemp 8年前發布 | 7K 次閱讀 iOS開發 移動開發

原文鏈接:UICollectionViews Now Have Easy Reordering

原本打算總結一下 UICollectionView 的一些用法,看到一篇比較好的文章,所以直接翻譯了。翻譯得比較生硬,見諒。

我超喜歡UICollectionView。相比UITableView,它容易自定義得多。現在我使用甚至使用 collection view 比使用 table view 還要頻繁了。在 iOS9 中,它開始支持使用起來很簡單的重排。在之前是不可能直接重排的,而且實現起來很麻煩。讓我們一起來看看 API。你可以在 Github 上找到對應的 Xcode 項目。

最簡單的實現重排是通過使用UICollectionViewController。它現在有一個新的屬性叫做installsStandardGestureForInteractiveMovement,作用是添加手勢(gestures)來重排 cells。這個屬性默認值為True,這意味著要使用它我們只需要重寫一個方法。

func collectionView(collectionView: UICollectionView,
    moveItemAtIndexPath sourceIndexPath: NSIndexPath,
    toIndexPath destinationIndexPath: NSIndexPath) {
    // move your data order
    // 可以留空
}

 

當前的 collection view 判定 items 可以被移動,因為moveItemAtIndexPath被重寫了。

【譯】UICollectionView 輕松重排

當我們希望在一個簡單的UIViewController中使用 collection view 時,會麻煩一點。我們也要實現之前提到的UICollectionViewDataSource方法,不過我們需要重寫installsStandardGestureForInteractiveMovement。不用擔心,也很簡單。UILongPressGestureRecognizer是一種持續性的手勢識別器并且完全支持拖動。

override func viewDidLoad() {
    super.viewDidLoad()

        longPressGesture = UILongPressGestureRecognizer(target: self, action: "handleLongGesture:")
    self.collectionView.addGestureRecognizer(longPressGesture)

}

func handleLongGesture(gesture: UILongPressGestureRecognizer) {

    switch(gesture.state) {

    case UIGestureRecognizerState.Began:
        guard let selectedIndexPath = self.collectionView.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else {
            break
        }
        collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
    case UIGestureRecognizerState.Changed:
        collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
    case UIGestureRecognizerState.Ended:
        collectionView.endInteractiveMovement()
    default:
        collectionView.cancelInteractiveMovement()
    }
}

</code></pre> </td> </tr> </tbody> </table>

 

我們保存了在 long press gesture 中不活的被選中的 index path 并且基于它是否有值決定允不允許拖動手勢生效。然后,我們根據手勢狀態調用一些新的 collection view 方法。

  • beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath):開始指定位置 cell 的交互移動。
  • updateInteractiveMovementTargetPosition(targetPosition: CGPoint):更新交互移動對象的位置
  • endInteractiveMovement():在你結束拖動手勢之后結束交互移動
  • cancelInteractiveMovement():取消交互移動

這些讓搞定拖動手勢非常容易。

【譯】UICollectionView 輕松重排

效果和標準的UICollectionViewController一樣。很酷對吧,不過更酷的是我們可以將我們自定義的 collection view layout 應用到重排中去。看看下面在簡單的瀑布視圖中的交互移動。

【譯】UICollectionView 輕松重排

嗯,看起來不錯,不過如果我們不想在移動的時候改變 cell 大小呢?選中的 cell 大小應該在交互移動時保持一致。這是可以實現的。UICollectionViewLayout也有一些其他的方法來負責重排。

  • func invalidationContextForInteractivelyMovingItems(targetIndexPaths: [NSIndexPath],
        withTargetPosition targetPosition: CGPoint,
        previousIndexPaths: [NSIndexPath],
        previousPosition: CGPoint) -> UICollectionViewLayoutInvalidationContext

    func invalidationContextForEndingInteractiveMovementOfItemsToFinalIndexPaths(indexPaths: [NSIndexPath], previousIndexPaths: [NSIndexPath], movementCancelled: Bool) -> UICollectionViewLayoutInvalidationContext </code></pre> </td> </tr> </tbody> </table>

     

    前一個在目標 indexPath 和之前的 indexPath 之間進行移動時調用。另一個類似,不過是在移動結束之后調用。有了這些我們就可以通過一些小手段達到我們的要求。

    internal override func invalidationContextForInteractivelyMovingItems(targetIndexPaths: [NSIndexPath],
        withTargetPosition targetPosition: CGPoint,
        previousIndexPaths: [NSIndexPath],
        previousPosition: CGPoint) -> UICollectionViewLayoutInvalidationContext {

    var context = super.invalidationContextForInteractivelyMovingItems(targetIndexPaths,
        withTargetPosition: targetPosition, previousIndexPaths: previousIndexPaths,
        previousPosition: previousPosition)
    
    self.delegate?.collectionView!(self.collectionView!, moveItemAtIndexPath: previousIndexPaths[0],
        toIndexPath: targetIndexPaths[0])
    
    return context
    

    } </code></pre> </td> </tr> </tbody> </table>

     

    解決方案非常清晰。獲取正在移動的 cell 之前和目標 index path。然后調用UICollectionViewDataSource來移動這些 item。

    【譯】UICollectionView 輕松重排

    不用懷疑,collection view 重排是一個非常棒的更新。UIKit 工程師干得太棒了!:)

    本文原鏈: 【譯】UICollectionView 輕松重排

    原文鏈接: UICollectionViews Now Have Easy Reordering

     本文由用戶 VernitaDemp 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!
  • sesese色