Я пытаюсь реализовать перетаскивание в моем NSOutlineView, но ни один из примеров кода, учебников или других вопросов, которые я нашел, похоже, не работает для моей ситуации. У меня есть NSOutlineView с его содержимым, связанным с NSTreeController. Массив содержимого контроллера дерева связан с NSMutableArray пользовательских объектов, которые имеют объекты childern того же типа. В виде схемы я могу добавлять и удалять объекты на любом уровне в иерархии. Все идет нормально.Как реализовать перетаскивание в NSOutlineView с помощью привязок?
Чтобы реализовать перетаскивание, я создал и подструктуру NSObject, которая будет служить в качестве источника данных вида контура. Я реализовал несколько методов, основанных на примере кода и сообщений, найденных в Stack Overflow. Я могу инициировать перетаскивание, но когда я делаю drop, outlineView: acceptDrop: item: childIndex: вызывается, но все значения, за исключением childIndex: nil. Значение для childIndex сообщает мне индекс местоположения drop в массиве, но не тот узел, на котором я находился в пределах иерархии.
Я предполагаю, что все остальные значения переданы в outlineView: acceptDrop: ... ноль, потому что я не полностью реализовал 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
Я не пытался использовать привязки и реализовал DnD для контурного представления, но для представления таблицы вам нужно подклассифицировать контроллер массива и добавить ваши методы DnD. Возможно, та же самая тактика будет работать для контура, если вы подклассифицируете NSTreeController. Я предполагаю, что было бы проще просто реализовать методы источника данных в уже созданном классе. – Monolo