我正在尝试在我的 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