如何使用绑定在NSOutlineView中实现拖放?

时间:2013-08-07 05:19:16

标签: cocoa cocoa-bindings nsoutlineview

我正在尝试在我的NSOutlineView中实现拖放,但是我找到的示例代码,教程或其他SO问题似乎都不适用于我的情况。我有一个NSOutlineView,其内容绑定到NSTreeController。树控制器的内容数组绑定到具有相同类型的childern对象的自定义对象的NSMutableArray。在大纲视图中,我可以添加和删除层次结构中任何级别的对象。到目前为止一切都很好。

为了实现我创建的拖放和NSObject子类,它将作为大纲视图的dataSource。我已经实现了一些方法,基于我在Stack Overflow上找到的示例代码和帖子。我可以启动拖动,但是当我执行drop时,调用outlineView:acceptDrop:item:childIndex:但是除了childIndex:之外的所有值都是nil。 childIndex的值告诉我数组中放置位置的索引,但不是告诉我在层次结构中的哪个节点。

我假设在outlineView:acceptDrop:...中传递的所有其他值都是nil,因为我还没有完全实现dataSource,我只是用它来控制拖放操作。我开始拖动时是否需要设置更多的粘贴板信息?如何在发生丢弃时找出我所处的节点?为什么outlineView中的所有值都是:acceptDrop:... nil?

这是大纲视图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

1 个答案:

答案 0 :(得分:0)

我在这个问题中描述的实现实际上工作得很好,但在尝试确定它是否正常工作时我犯了一个新手错误。我在- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index中设置了一个断点,以便检查传递给方法的值。我正在使用ARC,并且从未在方法中引用这些值,因此ARC从未保留它们,使调试器无法使用它们!