Views-based table drag and drop

  • Hi,

    My app has a views-based table with an NSTableCellView subclass. The represented object implements the NSPasteboardReading, NSPasteboardWriting, and NSCoding protocols. All the hooks are in place for drag and drop, but I need some conceptual help to figure how to implement it properly. I would like to be able to drag both within the document window to move rows, and between document windows to copy rows.

    For dragging within the same document it seemed easiest (at first) to just use tableView:writeRowsWithIndexes:toPasteboard: to store the NSIndexSet of the selected rows, and then to use that info to move the rows in the document's NSMutableArray. But in doing so, I found that draggingImageComponents is no longer called on my NSTableCellView subclass. And of course this isn't very useful information for dragging objects between documents. So obviously I need to use tableView:pasteboardWriterForRow:. But I don't quite understand how this behaves internally, or what data I should be returning.

    So I have a few questions. First, what should I be returning in pasteboardPropertyListForType:? At the moment I'm returning [NSKeyedArchiver archivedDataWithRootObject:self]. Since with this option the only data in the pasteboard is the archived object, how can I use that to delete the rows from their original positions before inserting them at the drop location? (I'm only dropping above rows, not on them.) Could I instead return the object pointer in pasteboardPropertyListForType: so that I have direct references to the original row objects? Should I use the NSTableView's selectedRowIndexes to delete the original rows, then unarchive and insert the new instances? Does any of this happen automagically, just by virtue of having NSPasteboardReading implemented? Should I be using an NSArrayController to save myself the trouble?

    Unfortunately the TableViewPlayground sample code isn't very helpful, because it doesn't demonstrate dragging custom class objects around, just file urls.

    Any and all guidance is much appreciated, especially if you can provide sample code for exactly this kind of situation.

    --
    Scott Lahteine
    Thinkyhead Software
  • You can put whatever data you want/need in the pasteboard item. Even multiple independent things. A handy trick is often to add a private type per item. This custom type can be as simple as the index of the item in the source list.

    > So obviously I need to use tableView:pasteboardWriterForRow:. But I don't quite understand how this behaves internally, or what data I should be returning.

    Lookup the NPasteboardWriting protocol.
    http://developer.apple.com/library/mac/#documentation/cocoa/reference/NSPas
    teboardWriting_Protocol/Reference/Reference.html


    -raleigh

    On Apr 12, 2012, at 1:34 PM, Scott Lahteine <slahteine...> wrote:

    > Hi,
    >
    > My app has a views-based table with an NSTableCellView subclass. The represented object implements the NSPasteboardReading, NSPasteboardWriting, and NSCoding protocols. All the hooks are in place for drag and drop, but I need some conceptual help to figure how to implement it properly. I would like to be able to drag both within the document window to move rows, and between document windows to copy rows.
    >
    > For dragging within the same document it seemed easiest (at first) to just use tableView:writeRowsWithIndexes:toPasteboard: to store the NSIndexSet of the selected rows, and then to use that info to move the rows in the document's NSMutableArray. But in doing so, I found that draggingImageComponents is no longer called on my NSTableCellView subclass. And of course this isn't very useful information for dragging objects between documents. So obviously I need to use tableView:pasteboardWriterForRow:. But I don't quite understand how this behaves internally, or what data I should be returning.
    >
    > So I have a few questions. First, what should I be returning in pasteboardPropertyListForType:? At the moment I'm returning [NSKeyedArchiver archivedDataWithRootObject:self]. Since with this option the only data in the pasteboard is the archived object, how can I use that to delete the rows from their original positions before inserting them at the drop location? (I'm only dropping above rows, not on them.) Could I instead return the object pointer in pasteboardPropertyListForType: so that I have direct references to the original row objects? Should I use the NSTableView's selectedRowIndexes to delete the original rows, then unarchive and insert the new instances? Does any of this happen automagically, just by virtue of having NSPasteboardReading implemented? Should I be using an NSArrayController to save myself the trouble?
    >
    > Unfortunately the TableViewPlayground sample code isn't very helpful, because it doesn't demonstrate dragging custom class objects around, just file urls.
    >
    > Any and all guidance is much appreciated, especially if you can provide sample code for exactly this kind of situation.
    >
    > --
    > Scott Lahteine
    > Thinkyhead Software
previous month april 2012 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
Go to today