在UICollectionViewDropDelegate,这个协议func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal可以帮忙解决。
查看下面的示例,了解我如何防止将项目从一个部分拖到另一部分:
在UICollectionViewDragDelegate中,我们使用itemsForBeginning 函数来传递有关对象的信息。可以看到,我把index和item传给了localObject
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let item = sectionViewModel[indexPath.section].items[indexPath.row]
let itemProvider = NSItemProvider(object: item.title as NSString)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = (item, indexPath)
return [dragItem]
}
在 UICollectionViewDropDelegate 中,我这样做了:
func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
if let object = session.items.first?.localObject as? (Item, IndexPath), object.0.status, let destinationIndexPath = destinationIndexPath, object.1.section == destinationIndexPath.section {
let itemAtDestination = sectionViewModel[destinationIndexPath.section].items[destinationIndexPath.row]
if itemAtDestination.status {
return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
}
return UICollectionViewDropProposal(operation: .forbidden)
}
根据Apple:
当用户拖动内容时,collection view 会重复调用此方法来确定如果拖放发生在指定位置,您将如何处理它。集合视图根据您的建议向用户提供视觉反馈。
在此方法的实现中,创建一个 UICollectionViewDropProposal 对象并使用它来传达您的意图。因为在用户拖动表格视图时会重复调用此方法,所以您的实现应该尽快返回。
我做了什么:
我有几个限制:
- 防止 item.status == true 转到同一部分中的项目
- 防止项目转到其他部分
GIF