【问题标题】:Reordering UICollectionView in iOS7在 iOS7 中重新排序 UICollectionView
【发布时间】:2016-04-25 10:10:26
【问题描述】:

我想构建一个 UICollectionView,或者使用类似的库来制作网格视图,我可以在其中重新排列单元格。我的应用程序支持 iOS 7,不幸的是 UICollectionView 方法 - (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath 仅适用于 iOS 9 及更高版本。

有什么方法可以在 iOS7 上实现“拖动和重新排序”集合视图单元格的效果?谢谢。

【问题讨论】:

    标签: ios objective-c uicollectionview


    【解决方案1】:

    好吧,我碰巧遇到了同样的问题,所以让我加两分钱。

    为了在重新排列单元格时获得与 UIKit 相同的效果,我采用了或多或少类似的方法,如下所述:

    1. 将长按手势识别器添加到集合视图中,以便 您将能够检测到哪个单元被窃听而不会搞砸 使用collectionView:didSelectItemAtIndexPath 方法。

    2. 当用户长按某个单元格时,对该单元格进行截图,将快照视图添加到集合视图中,然后隐藏该单元格。当用户在屏幕上移动手指时,更新快照的中心以编程方式移动它,这样看起来用户正在拖动单元格。

    3. 诀窍是决定何时以及如何交换单元格。随着快照的移动,它将与其他单元格相交。发生这种情况时,您应该更新数据源并调用moveItemAtIndexPath,以便交换原始单元格和快照相交的单元格的位置。

    4. 拖动结束时,从集合视图中移除快照并显示原始单元格。

    您可以将这些步骤映射到手势识别器的状态,以便我们知道您在每个状态下应该做什么:

    • 开始:1
    • 更改:2、3
    • 已结束、已取消、失败:4

    我在我的 github 帐户中添加了一个 example project,因此您可以下载并使用它。这里我只实现手势回调:

    注意:下面的代码可能不起作用,因为我丢弃了一些特定于实现的细节。但它应该显示基本意图。请从我的 github repo 下载完整代码。

    func longPressRecognized(recognizer: UILongPressGestureRecognizer) {
      let location = recognizer.locationInView(collectionView)
      let indexPath = collectionView.indexPathForItemAtPoint(location)
    
      switch recognizer.state {
        case .Began:
          let cell = collectionView.cellForRowAtIndexPath(indexPath)
          let snapshotView = cell.snapshotViewAfterScreenUpdates(true)
          snapshot.center = cell.center
          collectionView.addSubview(snapshotView)
          cell.contentView.alpha = 0.0 // hides original cell
    
        case .Changed:
          snapshotView.center = location // will follow user's finger.      
          dataSource.swap(originalCellIndexPath.item, indexPath.item) // swaps data
          collectionView.moveItemAtIndexPath(originalCellIndexPath, toIndexPath: indexPath) // swaps cells
          originalCellIndexPath = indexPath
    
        default:
          let cell = cellForRowAtIndexPath(originalCellIndexPath)
          cell.contentView.alpha = 1.0
          snapshotView.removeFromSuperview()
      }
    }
    

    这是你会得到的效果(在iOS 8.4模拟器上录制):

    【讨论】:

    • 非常感谢!我确实通过在项目中添加github.com/lxcid/LXReorderableCollectionViewFlowLayout 来实现这一点。
    • 如果你不添加 - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { ... }
    • @RemembranceNN 您所说的“似乎行不通”是什么意思?您能简要描述一下您遇到的问题类型吗?
    • @ozgur for me on iOS 11 & Objective C 在我覆盖函数 moveItemAtIndexPath 之前它根本不起作用
    • 作为例外工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-27
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多