简体   繁体   English

在iOS7中重新排序UICollectionView

[英]Reordering UICollectionView in iOS7

I want to build a UICollectionView, or use something similar library to make grid view, in which i can rearrange cells. 我想构建一个UICollectionView,或使用类似的库来制作网格视图,我可以在其中重新排列单元格。 My app supports iOS 7, and, unfortunately UICollectionView method - (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath is only available on iOS 9 and later. 我的应用程序支持iOS 7,不幸的是UICollectionView方法 - (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath仅适用于iOS 9及更高版本。

Is there any way i can achieve the effect of 'drag and reorder' collection view cells on iOS7? 有什么方法可以在iOS7上实现“拖动和重新排序”集合视图单元格的效果吗? Thanks. 谢谢。

Well, I happened to come across the very same issue, so let me add my two cents on this. 好吧,我碰巧碰到了同样的问题,所以让我加上我的两分钱。

In order to achieve to get the same effect of what UIKit does when rearranging cells, I followed a more or less similar approach described below: 为了获得与UIKit在重新排列细胞时所做的相同的效果,我遵循了下面描述的或多或少类似的方法:

  1. Add a long-press gesture recognizer into collection view so that you'd be able to detect which cell was tapped without messing up with collectionView:didSelectItemAtIndexPath method. 将长按手势识别器添加到集合视图中,这样您就可以检测到哪个单元格被轻敲而不会弄乱collectionView:didSelectItemAtIndexPath方法。

  2. When user long-presses on a cell, take a screenshot of that cell, add the snapshot view into collection view and then hide the cell. 当用户长按单元格时,获取该单元格的屏幕截图,将快照视图添加到集合视图中,然后隐藏单元格。 As the user moves his finger on the screen, update the snapshot's center to move it programmatically so it will look like the user is dragging the cell. 当用户在屏幕上移动手指时,更新快照的中心以便以编程方式移动它,使其看起来像用户正在拖动单元格。

  3. The trick is to decide when and how to swap cells. 诀窍是决定何时以及如何交换细胞。 As the snapshot moves around, it will intersect with other cells. 当快照移动时,它将与其他单元格相交。 When it happens, you should update your data source and call moveItemAtIndexPath so it will swap the positions of original cell and the cell which the snapshot intersects. 当它发生时,你应该更新你的数据源并调用moveItemAtIndexPath这样它就会交换原始单元格和快照相交的单元格的位置。

  4. When dragging ends, remove the snapshot from collection view and show the original cell. 拖动结束时,从集合视图中删除快照并显示原始单元格。

You can map those steps to gesture recognizer's states, so that we know what you should do at each state: 您可以将这些步骤映射到手势识别器的状态,以便我们知道您应该在每个州执行的操作:

  • Began : 1 开始 :1
  • Changed : 2, 3 改变 :2,3
  • Ended , Cancelled , Failed : 4 结束取消失败 :4

I put an example project in my github account, so you can download and play around with it. 我在我的github帐户中放了一个示例项目 ,因此您可以下载并使用它。 Here, I will just implement the gesture callback: 在这里,我将实现手势回调:

Note: The below code may not work because I threw away some implementation specific details. 注意:下面的代码可能不起作用,因为我丢弃了一些特定于实现的细节。 But it should show the basic intent. 但它应该表明基本意图。 Please download the full code from my github repo. 请从我的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()
  }
}

Here is the effect you will get (recorded on iOS 8.4 Simulator) : 以下是您将获得的效果(在iOS 8.4模拟器上录制)

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM