【问题标题】:Example for Drag and Drop inside NSCollectionViewNSCollectionView 中的拖放示例
【发布时间】:2017-02-19 15:58:21
【问题描述】:

我想使用它的拖放委托方法在NSCollectionView 中移动项目。我让它工作,直到该项目被丢弃。没有目标指示器(间隙),当释放鼠标时,项目会弹回。代表validateDropacceptDrop 永远不会被调用。 CollectionViewItems 显示来自自定义对象的数据:

func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {

    print("canDragItem", indexPaths)
    return true
}

func collectionView(_ collectionView: NSCollectionView, writeItemsAt indexPaths: Set<IndexPath>, to pasteboard: NSPasteboard) -> Bool {

    let indexData = Data(NSKeyedArchiver.archivedData(withRootObject: indexPaths))
    pasteboard.declareTypes(["my_drag_type_id"], owner: self)
    pasteboard.setData(indexData, forType: "my_drag_type_id")

    print("write data", indexData)
    return true
}


func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndex proposedDropIndex: UnsafeMutablePointer<Int>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionViewDropOperation>) -> NSDragOperation {

    print("validation")
    return NSDragOperation.move
}

func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, index: Int, dropOperation: NSCollectionViewDropOperation) -> Bool {

    let pb = NSPasteboard()
    let indexData = (pb.data(forType: "my_drag_type_id"))! as Data
    let indexPath = (NSKeyedUnarchiver.unarchiveObject(with: indexData)) as! IndexPath
    let draggedCell = indexPath.item as Int

    print("acceptDrop", draggedCell)


    return true
}

这到底是怎么回事...我认为在粘贴板中写入要拖动的项目数据有问题。任何建议。

【问题讨论】:

  • 检查方法的声明。缺少“路径”。
  • @Willeke 感谢您的回复,但您是什么意思?哪里缺少什么路径?谢谢!
  • 您的 validateDropacceptDrop 函数没有正确的参数。新版本有一个proposedIndexPathindexPath 参数。
  • 嗯,很有趣。我采用了 XCode 提示时建议的方法。我会检查一下。
  • @Willeke 就我而言,这就是问题的原因。 Xcode 自动完成仍然建议旧版本,并且它仍然存在于 NSCollectionView.h 中,但没有提及它不再工作。您能否将其作为答案提交,以便将问题标记为已回答?

标签: swift drag-and-drop nscollectionview


【解决方案1】:

此问题有两个可能的原因。在这种特殊情况下,Willeke 的回答是正确的。实际上,您仍然可以使用所有拖放委托函数的旧 indexSet 版本,但如果这样做,则必须确保 所有这些 都是旧版本,不要将旧版本和新的!

简而言之,如果您的 canDragItems: 委托函数有一个名为 indexPaths 的参数,那么请确保 writeItemsAt:validateDrop:acceptDrop: 函数也使用 IndexPaths,而不是 IndexSets。

其次,在我的例子中就是这种情况,检查您是否记得注册您希望集合视图响应的拖动类型,即viewDidLoad - 请参见下面的代码 sn-p - 和当然,首先在生成拖动数据时,在粘贴板中设置了相同的拖动类型!

collectionView.register(forDraggedTypes: [dragType])

【讨论】:

  • collectionView.registerForDraggedTypes 在 Swift 4 中重命名
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多