2

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

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

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

这是大纲视图数据源的实现:\@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
4

1 回答 1

0

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

于 2014-01-05T06:52:24.423 回答