NSOutlineView にドラッグ アンド ドロップを実装しようとしていますが、サンプル コード、チュートリアル、その他の SO に関する質問のいずれも、私の状況ではうまくいかないようです。コンテンツが NSTreeController にバインドされた NSOutlineView があります。ツリー コントローラのコンテンツ配列は、同じタイプの子オブジェクトを持つカスタム オブジェクトの NSMutableArray にバインドされます。アウトライン ビューでは、階層内の任意のレベルでオブジェクトを追加および削除できます。ここまでは順調ですね。
ドラッグ アンド ドロップを実装するために、アウトライン ビューのデータソースとして機能する NSObject サブクラスを作成しました。Stack Overflow で見つけたサンプル コードと投稿に基づいて、いくつかのメソッドを実装しました。ドラッグを開始できますが、ドロップすると、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