我正在使用iOS 11中引入的新Apple API在UICollectionView
上实现drag-n-drop。
我试图得到拖动的位置:
extension ViewController: UICollectionViewDropDelegate {
func collectionView(_ collectionView: UICollectionView,
dropSessionDidUpdate session: UIDropSession,
withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
let location = session.location(in: collectionView)
}
但它只代表我手指的位置。我需要得到整个框架,或者至少是它的起源。
我还尝试将y
触摸位置存储在我的单元格中然后执行类似dragLocation.y - touchLocationInCell.y
的操作,但这种方法并不准确:看起来预览会从触摸位置获得一些偏移。
我从事过类似的功能,可以分享一些细节。简而言之,似乎没有允许位置跟踪预览视图的选项。
从我的角度来看,我不会依赖预览视图的框架。在某些情况下,系统可以使预览视图比原始视图更小或更大。例如,当初始拖动视图大小大于其超视图大小时,可能会发生这种情况。在这种情况下,系统将使预览视图更小,以便为正在拖动的内容带来更多可见性。并且这种行为是不可预测的,系统可以基于某些内部逻辑应用这种转换。
我认为它的工作方式是因为拖放引擎不仅可以在一个特定应用程序内移动项目,还可以在其他应用程序之间移动项目。从那以后,拖放引擎应该是一个单独的系统进程,它处理所有拖放操作,包括预览大小和位置。
在拖动操作期间,系统会创建原始视图快照或从UIDragItem
的previewProvider返回的视图的快照。
然后它创建容器视图(私有UIPortalView
类的实例,下面有CAPortalLayer
),将快照安装到此容器中并显示容器视图。从那时起,预览视图位置由系统处理,并且没有公共API来访问此视图。
跟踪阻力位置的唯一可能方法是使用location(in view: UIView)
协议的UIDragDropSession
函数。
我希望这有帮助。
我正面临同样的问题(试图拖放UICollectionView日历事件单元)并且我得出结论(和Alex D.一样)iOS 11提供的“预览”视图无法解决这个问题。但是,我确实找到了一个不错的替代解决方案,基本上是从UICollectionViewCell.snapshot
创建自己的预览视图。然后,您可以拖动该视图,您将可以访问其位置,一旦用户“删除”视图,则根据自定义预览视图的位置创建新单元格并删除自定义预览视图。
你可以在这里看到一个有效的例子:https://github.com/zjfjack/JZCalendarWeekView/blob/master/JZCalendarWeekView/JZLongPressWeekView.swift#L385