我的下载页面上有一个关于如何通过拖放使用 NSOutlineView 的小演示:http://davedelong.com/downloads 它应该非常适用于 NSTableView,因为 NSOutlineView 是 NSTableView 的子类。
这是我在阅读文档大约一个月后所学到的知识的 5 分钟提炼。从 NSTableView 拖放内容时,使用了三种“基本”的 NSTableView 委托方法。它们是:
- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation;
- (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id < NSDraggingInfo >)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation;
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard;
第一个 tableView:acceptDrop:row:dropOperation: 用于当有人将某些东西拖到您的 NSTableView 上时。这很简单。在[info draggingPasteboard] 中可以找到有关丢弃的所有信息(包括被丢弃的内容)。如果删除成功返回YES,否则返回NO。
tableView:validateDrop:proposedRow:proposedDropOperation: 用于当有人想要将某些东西放到您的 NSTableView 上时。在这一点上,drop 的发起者并不重要。重要的是他们在你身上徘徊,你必须说出他们能做什么。例如,如果它们悬停在某一行(“proposedRow”)上,并且您不想让内容被放在该行上,则返回 NSDragOperationNone。或者,也许您想复制信息中的内容(返回 NSDragOperationCopy)。有a whole bunch of different kinds of operations you can signify。使用适合您需要的一种。 (这些返回值会相应地调整光标。因此,如果您返回 NSDragOperationCopy,那么光标将得到小绿色+ 圆圈。)
当用户在 NSTableView 中选择了一些行并开始拖动它们时,将调用最后一个方法 tableView:writeRowsWithIndexes:toPasteboard:。您现在必须为拖动的粘贴板提供与这些行对应的信息,以便可以将其拖放到其他位置。这是我如何使用此方法向粘贴板提供 NSManagedObjects 的简化示例:
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
[pboard declareTypes:[NSArray arrayWithObject:kMyCustomDragType] owner:self];
//get an array of URIs for the selected objects
NSMutableArray * rows = [NSMutableArray array];
NSArray * selectedObjects = [arrayOfManagedObjects objectsAtIndexes:rowIndexes];
for (NSManagedObject * o in selectedObjects) {
[rows addObject:[[o objectID] URIRepresentation]];
}
NSData * encodedIDs = [NSKeyedArchiver archivedDataWithRootObject:rows];
[pboard setData:encodedIDs forType:kMyCustomDragType];
return YES;
}
这背后的想法是,我正在对每个选定的 NSManagedObject 的 objectID 的 URIRepresentation 进行编码,并将其放在粘贴板上。我将这些数据放在“kMyCustomDragType”(NSString)类型下的 draggingPasteboard 上,这意味着只有表明它们接受 kMyCustomDragType 类型的 drop 的对象才能接收到这个 drop。我终于返回YES,表示我已成功将数据写入粘贴板。 (失败返回NO)
如果您可以让它工作,那么您可能已经获得了您需要的所有拖放功能的 90%。其他 10% 将来自陌生人的需求。一如既往,the documentation will be your best friend。