检测用户从UICollectionView中拖出项目?

时间:2013-08-09 05:42:57

标签: ios uicollectionview

我有一个UICollectionView,我希望能够触摸并拖动视图中的项目,从而删除它们。 (与Dock在OS X上的工作原理大致相同:拖出一些东西然后松开,它就被删除了。)

我做了一些研究,但几乎所有我发现的东西都是寻找拖放来重新排序的CollectionViews。我不需要重新排序(我很高兴只从源数组中删除给定索引处的项目,然后重新加载),我只需要检测项目何时移出View并释放。

所以我想我的问题是这些:

1)使用内置的CollectionView,某种itemWasDraggedOutsideViewFromIndex:方法还是可以做到这一点?

2)如果没有,是否可以使用子类完成(具体来说,对于CollectionView初学者来说可能是这样)?

3)您是否有可以推荐的代码示例或教程?

3 个答案:

答案 0 :(得分:3)

  1. 没有像你建议的内置方法。您可能想要做的是什么,但您必须使用手势识别器和适当的代码来处理它,以处理拖放操作。

  2. 我尝试使用子类来执行此操作,最后又将其放入我的视图控制器中。不过,在我的情况下,我在集合视图中拖出内容以及屏幕上的其他两个视图。

  3. 我不知道你是否有这本书,但我找到的最有用的东西是Erica Sadun的Core iOS6 Develper's Cookbook,它在Collection Views中有很好的拖放代码。我不认为它专门解决了CV之外的拖动,但对我来说解决方案是将手势识别器放在公共超视图上并始终使用其坐标而不是子视图的坐标。

  4. 我遇到的一个问题是我希望能够选择具有敲击和拖动的单元格,并且没有办法(尽管Apple的文档相反)要求单击手势在集合视图上失败。结果,我最终不得不使用长按手势来执行整个操作,并且没有用于长按的translationInView(有locationInView),因此需要一些额外的工作:

    iOS - Gesture Recognizer translationInView

    另一件让你更难或更容易的事情就是你拥有的可能掉落目标的数量。我有许多不同类型的视图(直接UIView,collectionview和scrollViews)。我发现有必要维护一个“放下目标”列表,并在移动拖动对象时测试与目标的交叉点。不知何故,你必须能够确定你正在交叉的视图是否是可以发生掉落的地方。

    如果你正在解决从视图中拖出某些东西以删除它的特定情况(比如拖动到垃圾桶可以查看),就是这样,这应该不复杂。你必须记住,当你进行变换时,你的框架变得毫无意义,但是中心仍然是好的;因此,您最终会使用中心来处理通常使用框架的所有内容。

    这是我在网上找到的最有帮助的东西;我并没有最终使用这个类,因为我认为在我的应用程序中实现它太复杂了。

    http://www.ancientprogramming.com/2012/04/05/drag-and-drop-between-multiple-uiviews-in-ios/

    希望这有所帮助。

答案 1 :(得分:3)

这是一个我一直在努力的帮助类,它实现了:实现:https://github.com/Ice3SteveFortune/i3-dragndrop,希望它有所帮助。有关如何在TestApp中使用它的示例。

<强>更新

大约一年后,现在这是一个全面的拖放式框架。希望这证明有用:https://github.com/ice3-software/between-kit

答案 2 :(得分:1)

是的。

1-使您的视图符合UIDropInteractionDelegate。

2-然后将此行添加到您的viewload或init中:

对于viewcontroller,添加到ViewDidload:

self.view.addInteraction(UIDropInteraction(delegate: self))

或者,对于UIView,将其添加到init:

self.addInteraction(UIDropInteraction(delegate: self))

3-然后在此处获取要拖动的项目的位置并对其进行使用:

func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
    print(session.location(in: self))
    return UIDropProposal(operation: .move)
}