3
votes

I have an NSOutlineView in which Ive implemented Drag and Drop, its values are populate via bindings.

Everything is working for the logic that I want, which is basically the ability to drop only in-between root level items, and children are not allowed to be dragged or dropped anywhere. So Im just trying to implement a re-order if you will.

My issue comes into play with where on the view my NSOutlineView is accepting drops. It appears that its only allowing me to drop on the far left side of the row. I can't seem to drop anywhere else. My rows are View based, and have an image view.

This one is working This shows it working

Here is it not working. This is it not working.

Heres my code for the acceptDrop.

- (NSDragOperation)outlineView:(NSOutlineView *)ov validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)childIndex {

    // Check to see what we are proposed to be dropping on
    NSTreeNode *targetNode = item;
    // A target of "nil" means we are on the main root tree
    if (targetNode == nil) {
        //If were dropping on the physical item lets say no
       if (childIndex == NSOutlineViewDropOnItemIndex) {
            return NSDragOperationNone;
       }
       //otherwise we are in-between so lets return move.
       return NSDragOperationMove;
    } else {
        return NSDragOperationNone;
    }
}

Is it possible this has something to do with my view setup instead of my NSOutlineView code?

UPDATE:

It works on the very top row no matter where my cursor is, but only on the far left for all other rows.

1
I just got the same exact problem. The proposedChildIndex is correct if you hover on the left side. But if you move the cursor to the middle, the proposedChildIndex is either 0 or -1. I'm smashing my head now, how did you fix this?Edward Anthony
@EdwardAnthony I answered it below.Kyle Browning
Yes, but using the solution below, I can’t get the right drop index (proposedChildIndex). It only returns 0 or -1 unless I move the cursor to the left. I don’t know if this is a bug or not. I tried to do git reset to yesterday commit, and it shows the same problem. I clearly remember this didn’t happen yesterday.Edward Anthony
After 3 hours of digging, I found that this is indeed a bug from AppKit, and your solution below works. Thank you.Edward Anthony

1 Answers

0
votes

This fixed it.

NSUInteger maxNumberOfRows = [[_hostController arrangedObjects] count];
// Check to see what we are proposed to be dropping on
NSTreeNode *targetNode = item;
// A target of "nil" means we are on the main root tree
if (targetNode == nil) {
    //If were dropping on the physical item lets say no
    if (childIndex == NSOutlineViewDropOnItemIndex) {
        [ov setDropItem:nil dropChildIndex:maxNumberOfRows];
        return NSDragOperationMove;
    }
    [ov setDropItem:nil dropChildIndex:childIndex];
    return NSDragOperationMove;
} else {
    //If its not a host we dont want to allow drop
    if (![self isHost:[item representedObject]]) {
        return NSDragOperationNone;
    }
    if (childIndex == NSOutlineViewDropOnItemIndex) {
        [ov setDropItem:nil dropChildIndex: [ov rowForItem:item]];
        return NSDragOperationMove;
    }
    return NSDragOperationNone;
}