drag-and-dropnscollectionviewnspasteboard

NSPasteBoard for Drag and Drop


I try to move an NSCollectionViewItem within the same NSCollectionView to allow reordering of the items. The collection view item is a custom item representing multiple labels with strings from a custom object Parameter:

class Parameter: NSObject {

var parameterName: String
var parameterNominal: Double
var parameterUpperTolerance: Double
var parameterLowerTolerance: Double
var parameterDistribution: String
var parameterNotes: String
var parameterDataArray: [Double]

// MARK: - Initialization Methods
...
}

Now, do I have to write the whole item/object into the 'NSPasteboard' to use drag and drop within the NSCollectionView correctly? Most of the drag 'n drop examples works with writing strings to pasteboard using ....register(forDraggedTypes: [NSPasteboardTypeString]).

I currently write one of the items string into the pasteboard and the drag 'n drop starts fine:

func collectionView(_ collectionView: NSCollectionView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting? {
    let pb = NSPasteboardItem()
    pb.setString(ParameterList.sharedInstance.parameters[indexPath.item].parameterName, forType: NSPasteboardTypeString)
    return pb
}

... but it looks strange to write only part of the object to pasteboard when moving of the complete object is requested, right?

How can I actually write my parameter object to the pasteboard (if needed)?

What is happening behind the scene with the data in the pasteboard when using drag and drop?

Thanks a lot!


Solution

  • I haven't used the pasteboard with collection views, but I have with outline views. If you are just reordering internally dragged items you don't really need to use the paste functionality fully - it is designed to allow generic types to be passed around across apps.

    You could just do the equivalent of this:

    func outlineView(_ outlineView: NSOutlineView, pasteboardWriterForItem item: Any) -> NSPasteboardWriting? {
        pasteboardItem.setString("Something to pass - not used", forType:MyConstants.pasteboardType)
        return pasteboardItem
    }
    

    You'll need to have some way of internally caching the dragged items in the function above. Then, in the accept drop you can just check for your pasteboard type and use your cache.