博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【译】UICollectionView 轻松重排
阅读量:7071 次
发布时间:2019-06-28

本文共 3720 字,大约阅读时间需要 12 分钟。

本文原链:

原文链接:

原本打算总结一下 UICollectionView 的一些用法,看到一篇比较好的文章,所以直接翻译了。翻译得比较生硬,见谅。

我超喜欢UICollectionView。相比UITableView,它容易自定义得多。现在我使用甚至使用 collection view 比使用 table view 还要频繁了。在 iOS9 中,它开始支持使用起来很简单的重排。在之前是不可能直接重排的,而且实现起来很麻烦。让我们一起来看看 API。你可以在 上找到对应的 Xcode 项目。

最简单的实现重排是通过使用UICollectionViewController。它现在有一个新的属性叫做installsStandardGestureForInteractiveMovement,作用是添加手势(gestures)来重排 cells。这个属性默认值为True,这意味着要使用它我们只需要重写一个方法。

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

当前的 collection view 判定 items 可以被移动,因为moveItemAtIndexPath被重写了。

当我们希望在一个简单的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()        }    }

我们保存了在 long press gesture 中不活的被选中的 index path 并且基于它是否有值决定允不允许拖动手势生效。然后,我们根据手势状态调用一些新的 collection view 方法。

  • beginInteractiveMovementForItemAtIndexPath(indexPath: NSIndexPath):开始指定位置 cell 的交互移动。

  • updateInteractiveMovementTargetPosition(targetPosition: CGPoint):更新交互移动对象的位置

  • endInteractiveMovement():在你结束拖动手势之后结束交互移动

  • cancelInteractiveMovement():取消交互移动

这些让搞定拖动手势非常容易。

效果和标准的UICollectionViewController一样。很酷对吧,不过更酷的是我们可以将我们自定义的 collection view layout 应用到重排中去。看看下面在简单的瀑布视图中的交互移动。

嗯,看起来不错,不过如果我们不想在移动的时候改变 cell 大小呢?选中的 cell 大小应该在交互移动时保持一致。这是可以实现的。UICollectionViewLayout也有一些其他的方法来负责重排。

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

前一个在目标 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}

解决方案非常清晰。获取正在移动的 cell 之前和目标 index path。然后调用UICollectionViewDataSource来移动这些 item。

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

转载地址:http://kgkml.baihongyu.com/

你可能感兴趣的文章
飞天5K实战经验:大规模分布式系统运维实践
查看>>
参加51CTO学院软考培训,我通过啦
查看>>
html5新增标签
查看>>
专为SaaS而生的PaaS平台!
查看>>
idou老师教你学Istio :5分钟简析Istio异常检测
查看>>
UIImage resize(拉伸)
查看>>
零基础如何高效的学习java开发?
查看>>
城市热点认证计费系统应用
查看>>
雷军:明后年会迎来5G手机的全面换机潮
查看>>
Python类的一般形式和继承
查看>>
高朋网13个地方分站整体被撤
查看>>
基于binlog方式搭建MySQL主从
查看>>
md test
查看>>
解决 Nginx + PHP-FPM (Permission denied)报错的办法
查看>>
Cisco IPSec ××× 设计总结
查看>>
python excel 转 csv
查看>>
xmake 工程描述语法更新
查看>>
linux5.4 构建LAMP网站服务平台
查看>>
Cookie与Session的区别
查看>>
比传统事务快10倍?一张图读懂阿里云全局事务服务GTS
查看>>