4

我必须在我的应用程序中的 NSTableViews 都显示存储为“CoreData”的数据。TableViews 是非常基本的,就像整个程序一样。

右边的 TableView 显示了一个清单列表,左边显示了这个清单的内容。现在我想允许用户将清单内的项目拖到另一个清单中。

我在网上找到了一些教程和示例代码,但对于我对 Cocoa 的理解来说,它们是压倒性的。如果有人可以通过简短易懂的说明提及网页或教程等,那就太好了。

非常感谢

编辑:虽然应该很明显,但我的应用程序是用 Cocoa 编写的并在 Mac 上运行。

4

1 回答 1

27

我在我的下载页面上有一个关于如何通过拖放使用 NSOutlineView 的小演示:http: //davedelong.com/downloads 它应该非常适用于 NSTableView,因为 NSOutlineView 是 NSTableView 的子类。

这是我在阅读文档大约一个月后所学到的知识的 5 分钟提炼。从 NSTableView 拖放内容时,使用了三种“基本”的 NSTableView 委托方法。他们是:

  1. - (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation;

  2. - (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id < NSDraggingInfo >)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation;

  3. - (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)。您可以表示一大堆不同类型的操作。使用适合您需要的一种。(这些返回值会相应地调整光标。因此,如果您返回 NSDragOperationCopy,那么光标将获得绿色的小+圆圈。)

最后一个方法,tableView:writeRowsWithIndexes:toPasteboard:当用户在你的 NSTableView 中选择了一些行并开始拖动它们时调用。您现在必须为拖动的粘贴板提供与这些行对应的信息,以便可以将其拖放到其他位置。这是我如何使用此方法向粘贴板提供 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 类型的拖放的对象才能接收此拖放。我终于回来YES表明我已成功将数据写入粘贴板。(NO如果失败则返回)

如果你可以让它工作,那么你可能已经拥有了你需要的所有拖放功能的 90%。其他 10% 将来自陌生人的需求。与往常一样,文档将是您最好的朋友

于 2009-09-05T15:45:30.003 回答