在 iOS 13 上拖动时,UICollectionView 单元格捕捉到原始位置

Posted

技术标签:

【中文标题】在 iOS 13 上拖动时,UICollectionView 单元格捕捉到原始位置【英文标题】:UICollectionView cell snaps to original position when dragged on iOS 13 【发布时间】:2020-01-07 07:41:26 【问题描述】:

我有一个UICollectionViewController,它使用交互式移动 API 来支持单元格的重新排序。当一个单元格被拖到一个不同的位置,然后回到它的原始位置时,它会捕捉/跳转到适当的位置。这只发生在 ios 13 上,不会发生在 iOS 11 或 iOS 12 上。

https://imgur.com/kKq9xr3

我使用以下方法来处理集合视图单元格的长按:

@objc private func handleLongPress(_ recognizer: UILongPressGestureRecognizer) 
    switch recognizer.state 
    case .began:
        guard let selectedIndexPath = collectionView.indexPathForItem(at: recognizer.location(in: collectionView)) else 
            break
        
        collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)

    case .changed:
        collectionView.updateInteractiveMovementTargetPosition(recognizer.location(in: collectionView))

    case .ended:
        collectionView.endInteractiveMovement()

    default:
        collectionView.cancelInteractiveMovement()
    

这里有一个最小的可重现示例:https://github.com/wsun/ios13DragDrop

我想坚持使用交互式移动 API,而不是使用更新的 iOS 11 拖放 API,因为它允许控制用户可以将单元格拖动到的位置。由于我没有做任何特别新颖的事情,我怀疑这可能是 iOS 13 中的 UIKit 回归。有没有人有任何建议或解决方法来解决这个问题?

【问题讨论】:

您的代码引用了许多未知方法。这使得无法详细了解您在做什么。 @matt 感谢您的反馈,我已经删除了这些方法——它们与这种行为无关。我还为这个问题添加了一个最小的可重现示例。 @wsun 我也遇到了同样的问题,你找到解决办法了吗? @sash,刚刚添加了我的解决方案 - 希望对您有所帮助! 这似乎是 iOS 13 上的一个错误。检查此radar://7401200。 【参考方案1】:

由于 iOS11 的拖放功能已内置在 CollectionViews 中,因此您不再需要这样做。

https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/supporting_drag_and_drop_in_collection_views

【讨论】:

感谢您的回答!但是,我不确定 iOS 11 拖放 API 是否适用于我的情况 - 我想控制拖动动作(例如,仅锁定到垂直轴,如视频中所示),而 UICollectionViewDragDelegate 没有提供一个接口来控制它,就像旧的交互式移动 API 使用 updateInteractiveMovementTargetPosition 我没有通读所有那篇文章,但没有声明对 collectionView 的拖放代表已经为我修复了它。但这也意味着您不能拥有 contextMenuConfigurationForItemAt;可能是因为它们都是长按【参考方案2】:

经过一番折腾,我决定继续实现我自己的集合视图移动 API,它反映了 beginInteractiveMovementForItemupdateInteractiveMovementTargetPositionendInteractiveMovement 方法。

SO answer 有助于说明您必须重新实现的内部逻辑,如果合适,您还需要在拖动和占位符单元格上实现滚动。特别是,您将创建拖动单元格的快照(暂时隐藏原始单元格)并在拖动时更新临时快照单元格的位置/样式。

这是 Apple 已经完成的大部分工作,因此,如果您不是绝对需要控制拖动或交换行为,绝对推荐使用 iOS 11 拖动 API(@trapper 提到)。

我发现其他人似乎已就此行为提交了radar,因此希望 Apple 会在未来的某个时候注意到并修复!

【讨论】:

2020 年 12 月 1 日,iOS 13 上仍然存在问题...

以上是关于在 iOS 13 上拖动时,UICollectionView 单元格捕捉到原始位置的主要内容,如果未能解决你的问题,请参考以下文章

拖动底部子视图之一时平滑更新顶部子视图(iOS)

iOS中的简单对象拖动

在 iOS 中制作一个可拖动的 UIView 捕捉到边缘

ios16桌面图标转盘效果

为啥我不能 CTRL 拖动情节提要的动作?

UISlider拖动在iOS中表现异常