Pregunta

I'm trying to implement drag and drop in my NSOutlineView but none of the example code, tutorials or other SO questions that I've found seem to work for my situation. I have an NSOutlineView with its content bound to an NSTreeController. The tree controller's Content Array is bound to an NSMutableArray of custom objects that have childern objects of the same type. In the outline view I can add and remove objects at any level in the heirarchy. So far so good.

To implement drag and drop I created and NSObject sublass that will serve as the outline view's dataSource. I have implemented a few methods, based on sample code and posts I found on Stack Overflow. I can initiate a drag, but when I do the drop, outlineView: acceptDrop: item: childIndex: is called but all of the values except for childIndex: are nil. The value for childIndex tells me the index of the drop location within the array but not which node I am at within the heirarchy.

I assume that all the other values passed in outlineView: acceptDrop: ... are nil because I haven't fully implemented dataSource, I'm only using it to control the drag and drop operation. Do I need to set up more pasteboard information when I start the drag? How do I find out what node I'm at when the drop occurs? Why are all the values in outlineView: acceptDrop: ... nil?

Here is the implementation of the outline views dataSource: \ @implementation TNLDragController

- (void)awakeFromNib {
    [self.titlesOutlineView registerForDraggedTypes:[NSArray arrayWithObject:@"Event"]];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard {
    NSLog(@"starting a drag");

    NSString *pasteBoardType = @"Event";
    [pboard declareTypes:[NSArray arrayWithObject:pasteBoardType] owner:self];

      return YES;
}

- (NSDragOperation)outlineView:(NSOutlineView *)outlineView
                  validateDrop:(id < NSDraggingInfo >)info
                  proposedItem:(id)item
            proposedChildIndex:(NSInteger)index {
    NSLog(@"validating a drag operation");
    return NSDragOperationGeneric;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index {
    NSLog(@"accepting drag operation");
    //todo: move the object in the data model;
    NSIndexPath *path = [self.treeController selectionIndexPath]; // these three values are nil too.
    NSArray *objects = [self.treeController selectedObjects];
    NSArray *nodes = [self.treeController selectedNodes];
    return YES;
}

// This method gets called by the framework but the values from bindings are used instead
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
     return NULL;
}

/*
 The following are implemented as stubs because they are required when
 implementing an NSOutlineViewDataSource. Because we use bindings on the
 table column these methods are never called. The NSLog statements have been
 included to prove that these methods are not called.
 */
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
     NSLog(@"numberOfChildrenOfItem");
     return 1;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
     NSLog(@"isItemExpandable");
     return YES;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
     NSLog(@"child of Item");
     return NULL;
}
@end
¿Fue útil?

Solución

the implementation I described in this question was, in fact working just fine, but I made a rookie mistake when trying to determine if it was working. I set a breakpoint in - (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index in order to examine the values that were being passed into the method. I'm using ARC and the values were never referenced within the method so ARC never retained them, making them unavailable to the debugger!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top