Example for Drag and Drop inside NSCollectionView

大憨熊 提交于 2019-12-04 05:33:44

问题


I would like to move items inside a NSCollectionView using its drag and drop delegate methods. I get it working until the item should get dropped. There is no destination indicator (gap) and when releasing the mouse the item is bouncing back. The delegates validateDrop and acceptDrop never gets called. The CollectionViewItems are showing data from custom objects:

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
}

What the heck... I think there is something wrong with writing the item-data to be dragged in the pasteboard. Any suggestions.


回答1:


There are two possible causes of this issue. In this specific case Willeke's response is correct. You can in fact still use the old indexSet versions of all the drag-and-drop delegate functions, but if you do then you must make sure that all of them are the old versions, no mixing old and new!

In short, if your canDragItems: delegate function has a parameter called indexPaths, then ensure that writeItemsAt:, validateDrop: and acceptDrop: functions also make use of IndexPaths, not IndexSets.

Secondarily, and this was the case in my instance, check that you have remembered to register for the drag types you want your collection view to respond to somewhere sensible, i.e. viewDidLoad - see the code snippet below - and of course that the same drag type is being set in the pasteboard when generating the drag data in the first place!

collectionView.register(forDraggedTypes: [dragType])


来源:https://stackoverflow.com/questions/42329390/example-for-drag-and-drop-inside-nscollectionview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!