`dropSessionDidUpdate` 中的 UICollectionViewDropDelegate 错误的目标索引路径
UICollectionViewDropDelegate wrong destination index path in `dropSessionDidUpdate`
我正在尝试在这个狭长的集合视图中实现拖放操作:
它具有水平布局,包含不同大小的单元格和部分。
拖动交互效果很好,但我发现 UICollectionViewDropDelegate 中存在问题:
func collectionView(
_ collectionView: UICollectionView,
dropSessionDidUpdate session: UIDropSession,
withDestinationIndexPath destinationIndexPath: IndexPath?)
-> UICollectionViewDropProposal {
if let destination = destinationIndexPath {
print(destination) // Prints WRONG index path!!!
return UICollectionViewDropProposal(
operation: .move, intent: .insertAtDestinationIndexPath
)
}
return UICollectionViewDropProposal(
operation: .cancel, intent: .unspecified
)
}
错误的目标索引路径传递给 collectionView(_:dropSessionDidUpdate:withDestinationIndexPath:)
。
因此,我无法正确确定该部分并确定该部分是否可用。
所以,这是 UIKit 的一个错误。正确的目标索引路径可以计算如下:
func collectionView(
_ collectionView: UICollectionView,
dropSessionDidUpdate session: UIDropSession,
withDestinationIndexPath destinationIndexPath: IndexPath?)
-> UICollectionViewDropProposal {
// Calculating location in view
let location = session.location(in: collectionView)
var correctDestination: IndexPath?
// Calculate index inside performUsingPresentationValues
collectionView.performUsingPresentationValues {
correctDestination = collectionView.indexPathForItem(at: location)
}
guard let destination = correctDestination else {
return UICollectionViewDropProposal(
operation: .cancel, intent: .unspecified
)
}
// check destination
// ...
}
为了修复这个错误,首先,我尝试使用 location(in:)
和 indexPathForItem(at:)
的组合。生成的索引路径等于委托方法提供的 destinationIndexPath
。为什么?我的注意力被 UIDataSourceTranslating 吸引了。它是一种协议,允许集合和 table 视图显示用于拖放的占位符单元格,而无需更改实际数据源。当拖放交互结束时,可以轻松删除占位符。所以,我假设
destinationIndexPath
是在 indexPathForItem(at:)
的帮助下计算出来的
- 它忽略了由 UIDataSourceTranslating 创建的占位符,这是一个错误
然后我尝试将indexPathForItem(at:)
包装成performUsingPresentationValues(_:)
并且接收到的索引路径是正确的!
我正在尝试在这个狭长的集合视图中实现拖放操作:
它具有水平布局,包含不同大小的单元格和部分。
拖动交互效果很好,但我发现 UICollectionViewDropDelegate 中存在问题:
func collectionView(
_ collectionView: UICollectionView,
dropSessionDidUpdate session: UIDropSession,
withDestinationIndexPath destinationIndexPath: IndexPath?)
-> UICollectionViewDropProposal {
if let destination = destinationIndexPath {
print(destination) // Prints WRONG index path!!!
return UICollectionViewDropProposal(
operation: .move, intent: .insertAtDestinationIndexPath
)
}
return UICollectionViewDropProposal(
operation: .cancel, intent: .unspecified
)
}
错误的目标索引路径传递给 collectionView(_:dropSessionDidUpdate:withDestinationIndexPath:)
。
因此,我无法正确确定该部分并确定该部分是否可用。
所以,这是 UIKit 的一个错误。正确的目标索引路径可以计算如下:
func collectionView(
_ collectionView: UICollectionView,
dropSessionDidUpdate session: UIDropSession,
withDestinationIndexPath destinationIndexPath: IndexPath?)
-> UICollectionViewDropProposal {
// Calculating location in view
let location = session.location(in: collectionView)
var correctDestination: IndexPath?
// Calculate index inside performUsingPresentationValues
collectionView.performUsingPresentationValues {
correctDestination = collectionView.indexPathForItem(at: location)
}
guard let destination = correctDestination else {
return UICollectionViewDropProposal(
operation: .cancel, intent: .unspecified
)
}
// check destination
// ...
}
为了修复这个错误,首先,我尝试使用 location(in:)
和 indexPathForItem(at:)
的组合。生成的索引路径等于委托方法提供的 destinationIndexPath
。为什么?我的注意力被 UIDataSourceTranslating 吸引了。它是一种协议,允许集合和 table 视图显示用于拖放的占位符单元格,而无需更改实际数据源。当拖放交互结束时,可以轻松删除占位符。所以,我假设
destinationIndexPath
是在indexPathForItem(at:)
的帮助下计算出来的
- 它忽略了由 UIDataSourceTranslating 创建的占位符,这是一个错误
然后我尝试将indexPathForItem(at:)
包装成performUsingPresentationValues(_:)
并且接收到的索引路径是正确的!