Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag&Drop is not enabled for a NSOutlineView although I've implemented delegate methods

I'm not able to enable drag and drop for a NSOutlineView. I've implemented the related method of the NSOutlineView Delegate.

But it seems that when I click an item, I can't even dragging it (I don't see animation).

- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index
{
    return YES;
}

- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{
    return NSDragOperationMove; //not sure about this one.
}

thanks

UPDATE:

I'm implementing forOSX >= 10.5

- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard
{
    NSString *pasteBoardType = [self pasteboardTypeForTableView:outlineView];
    [pboard declareTypes:[NSArray arrayWithObject:pasteBoardType] owner:self];

    NSData *rowData = [NSKeyedArchiver archivedDataWithRootObject:items];
    [pboard setData:rowData forType:pasteBoardType];
        return YES;
}
like image 575
aneuryzm Avatar asked Feb 20 '23 23:02

aneuryzm


2 Answers

The methods you implemented are just for the destination of the drag. You still need to implement the dragging source methods. For whatever reason Apple's NSOutlineViewDataSource Protocol documentation is missing these methods but you have two options:

  1. If you are building 10.7+ use Xcode's Open Quickly command to look in NSOutlineView.h and find the relevant methods. Also check out the DragNDropOutlineView sample app.

  2. If you are supporting previous OS's then use NSTableView's delegate methods. See NSTableViewDataSource Protocol Reference. Remember that NSOutlineView is a subclass of NSTableView and can use the table view methods.

At a minimum you will probably want to implement outlineView:writeItems:toPasteboard:

/* Dragging Source Support - Optional for single-image dragging. This method is called after
it has been determined that a drag should begin, but before the drag has been started.  To 
refuse the drag, return NO.  To start a drag, return YES and place the drag data onto the 
pasteboard (data, owner, etc...).  The drag image and other drag related information will 
be set up and provided by the outline view once this call returns with YES.  The items array 
is the list of items that will be participating in the drag.
*/
- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard;

Update:

If the item can be dragged but won't drop on anything then most likely outlineView:validateDrop:proposedItem:proposedChildIndex: is not being called. This would mean you haven't registered the pasteboard type which you do with registerForDraggedTypes:. You would do this somewhere in the view controller, probably in awakeFromNib.

[outlineView registerForDraggedTypes:[NSArray arrayWithObject:@"myPasteBoardType"]];

To move the item (and all its children) modify your model in outlineView:acceptDrop:item:childIndex:. Then send reloadData to the outlineView.

like image 96
Nathan Kinsinger Avatar answered May 09 '23 16:05

Nathan Kinsinger


To make your outline view a dragging source, you must implement:

- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard;

This should address what you described, but you've got a lot more work to do beyond this.

like image 34
Extra Savoir-Faire Avatar answered May 09 '23 17:05

Extra Savoir-Faire