2016-04-24 89 views
5

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

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

回答

9

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

为了达到获得的清理单元时UIKit中做什么一样的效果,我也跟着下面描述或多或少类似的方法:

  1. 添加长按手势识别成集视图,以便那 你将能够检测到哪个单元被点击,而不会搞砸 与collectionView:didSelectItemAtIndexPath方法。

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

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

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

您可以映射这些步骤手势识别器的状态,让大家知道你应该在每个国家做什么:

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

我把一个example project放在我的github帐户中,所以你可以下载并使用它。在这里,我将只实现手势回调:

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

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模拟器)效果:

enter image description here

+1

非常感谢你!我通过将https://github.com/lxcid/LXReorderableCollectionViewFlowLayout添加到项目中实现了这一目标。 –

+0

这似乎是行不通的好,如果你不加 - (空)的CollectionView:(UICollectionView *)的CollectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { ... } – RemembranceNN

+0

@RemembranceNN你是什么意思“似乎不会很好”?你能简单描述一下你遇到的问题吗? – ozgur