你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 現在,UICollectionViews有了簡單的重排功能

現在,UICollectionViews有了簡單的重排功能

編輯:IOS開發基礎

003.jpg

本文由CocoaChina譯者@空城惠翻譯
原文:UICollectionViews Now Have Easy Reordering

我是UICollectionView的忠實粉絲。這個類比起它的老哥UITableView類具有更高的可定制性。現在我用collection view的次數要比用table view還多。隨著iOS9的到來,它支持簡單的重排。在此之前,重排不可能有現成的方法,同時這樣做也是件痛苦的工作。現在讓我們來看看API,你可以在GitHub找到相應的Xcode工程。

添加簡單重排的最簡單的方式是用UICollectionViewController。它現在有了一個新的屬性叫installsStandardGestureForInteractiveMovement(為交互式移動工作設置標准手勢),這個屬性的添加使得我們可以用標准手勢來對cell單元進行重新排序。該屬性默認值為true,這意味著我們只需要重載一個方法就可以讓它正常工作。

override?func?collectionView(collectionView:?UICollectionView,
????moveItemAtIndexPath?sourceIndexPath:?NSIndexPath,
????toIndexPath?destinationIndexPath:?NSIndexPath)?{
????//?move?your?data?order
}

Collection view推斷每個item(元素)可以被移動,因為moveItemAtIndexPath函數被重載了。

011.gif

當我們想使用一個帶有collection view的簡單的UIViewController時,事情變得更加復雜。我們還需要實現之前提到的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()
????????}
????}

我們儲存了被選擇的索引路徑,這個路徑從longPressGesture handler(長按手勢處理器)中獲得,這個路徑還取決於它是否有任何我們允許的,跟平移手勢相關的值。接下來我們根據手勢狀態調用一些新的collection view方法:

  • beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath)?開始在特定的索引路徑上對cell(單元)進行Interactive Movement(交互式移動工作)。

  • updateInteractiveMovementTargetPosition(targetPosition: CGPoint)?在手勢作用期間更新交互移動的目標位置。】

  • endInteractiveMovement()?在完成手勢動作後,結束交互式移動

  • cancelInteractiveMovement()?取消Interactive Movement。

這讓處理平移手勢更容易理解了。

012.gif

機器反應跟標准的UICollectionViewController一樣,真的很酷,但是還有更酷的--我們能對自定義的collection view layout(collection集合視圖布局)申請重排,下面是在waterfall layout(瀑布布局)裡對Interactive Movement的測試。

013.gif

嗯哼,看起來很酷,但如果我們不想在移動cell(單元)的時候改變它們的大小,那該怎麼做?被選擇的cell(單元)的大小在Interactive Movement期間應該保持原樣。這是可行的。UICollectionViewLayout有附加的方法來處理重排。

func?invalidationContextForInteractivelyMovingItems(targetIndexPaths:?[NSIndexPath],
????withTargetPosition?targetPosition:?CGPoint,
????previousIndexPaths:?[NSIndexPath],
????previousPosition:?CGPoint)?->?UICollectionViewLayoutInvalidationContext
????
func?invalidationContextForEndingInteractiveMovementOfItemsToFinalIndexPaths(indexPaths:?[NSIndexPath],
????previousIndexPaths:?[NSIndexPath],
????movementCancelled:?Bool)?->?UICollectionViewLayoutInvalidationContext

第一個函數在元素的Interactive Movement期間被調用,它帶有target(目標元素)和先前的cell的indexPaths(索引地址)。第二個與第一個函數類似,但它只在Interactive Movement結束後才調用。通過這些知識我們能通過一點小竅門,實現我們的需求。

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
}

取得當前正在移動的cell的之前的和目標索引路徑,然後調用UICollectionViewDataSource方法來移動這些item(元素)。

014.gif

毫無疑問,collection view的重排是一個出色的附加功能,UIKit前端框架工程師干得漂亮!:)

P.S:我要感謝Douglas Hill對於代碼完善的一些建議。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved