UICollectionViews Now Have Easy Reordering
0x00 前言
这篇文章是 NSHint 上的 UICollectionViews Now Have Easy Reordering。你可以直接去看英文的原文。
0x01 正文
哥是 UICollectionView
的头号大粉丝,它比它的老大哥 UITableView
更加的可定制化,现在哥经常使用 collection view 而不使用 table view。而且 iOS 9 也支持简单重排了。在这之前不太可能实现,并且要实现意味着这是一件非常痛苦的事情。让我们一起来瞧一瞧这个 API。你可以在 GitHub 上找到这个 Xcode 项目。
使用 UICollectionViewController
是做简单重排的最简单的方法,现在,它多了一个新的属性 installsStandardGestureForInteractiveMovement
,增加了重排 cells 的标准手势。这个属性默认为 true
,这意味着我们只需要重载一个方法就可以完成我们想要的功能了,真是太赞了!
1 | override func collectionView(collectionView: UICollectionView, |
因为 moveItemAtIndexPath
被重载了,所以 collection view 能推断出它的 items 能够移动。
当我们想要在一个简单的 UIViewController
中使用 collection view,事情会变得非常繁琐。我们依然需要实现上述的 UICollectionViewDataSource
的几个方法,但是我们需要重写 installsStandardGestureForInteractiveMovement
,不用担心,它也非常容易支持的。supported.UILongPressGestureRecognizer
是一个连续的手势识别,并且完全支持 panning。
1 | override func viewDidLoad() { |
我们保存了在长按手势 handler 中获得的选择的 item 的下标,and depending on wether it has any value we allow to pan gesture to kick in(这里的 wether 应该是 whether 吧)。然后,我们根据手势的状态调用一些 collection view 新的方法:
beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath)
在特定的 index path 开始 cell 的交互移动动画updateInteractiveMovementTargetPosition(targetPosition: CGPoint)
在手势的过程中更新目标位置的交互移动动画endInteractiveMovement()
在你结束 pan 手势之后结束交互移动动画cancelInteractiveMovement()
取消交互移动动画
这让处理 pan 手势显而易见。
这行为和标准的 UICollectionViewController
是一样的。非常 cool,不过,我们可以用我们自己定制的 collection view layout 来将 collection view 的重排实现得更 cool!先来看看简单的瀑布流布局的交互移动动画。
嗯哼,看起来很 cool,但是如果我们不想在移动的过程中改变 cell 的大小呢?在交互移动动画的过程中,选择的 cell 的大小应该保持不变,这是可能的。UICollectionViewLayout
也有另外的方法来处理重排。
1 | func invalidationContextForInteractivelyMovingItems(targetIndexPaths: [NSIndexPath], |
前一个方法是在目标 IndexPath 与之前的 cell 的 indexPath 的 cells 交互移动动画中被调用的,后一个方法也是类似的,但是它只在交互移动动画结束之后被调用。有了这些知识,我们就可以使用一个小技巧来实现我们的需求了。
1 | internal override func invalidationContextForInteractivelyMovingItems(targetIndexPaths: [NSIndexPath], |
解决办法非常简单粗暴,抓取当前正在移动的 cell 的之前和目标的 index path,然后调用 UICollectionViewDataSource
的方法来移动 items。
毫无疑问,一个 collection view 重排是一个非常神奇的 addition。UIKit 工程师们,干得漂亮!:)
P.S: 非常感谢 Douglas Hill 在我们的代码中提出的一些改进,谢谢你!继续保持!