使用CoreData存储对NSTableView进行Drag'n'Drop支持

时间:2009-09-05 10:52:33

标签: cocoa core-data drag-and-drop nstableview

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

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

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

非常感谢

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

1 个答案:

答案 0 :(得分:27)

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

这是对我在阅读文档大约一个月后学到的东西的5分钟升华。从NSTableViews拖放东西时,有三种“基本”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;

  4. 当有人将某些内容拖到您的NSTableView上时,会使用第一个tableView:acceptDrop:row:dropOperation:。这很简单。有关丢弃的所有信息(包括被删除的内容)都可以在[info draggingPasteboard]中找到。如果删除成功则返回YES,否则返回NO

    当有人想要将某些内容放到您的NSTableView上时,会使用

    tableView:validateDrop:proposedRow:proposedDropOperation:。在这一点上,跌落的发起者并不重要。重要的是他们在你身上徘徊,你必须说出他们能做些什么。例如,如果它们悬停在某一行('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并将其放在粘贴板上。我将这些数据放在draggingPasteboard下的类型为“kMyCustomDragType”(NSString),这意味着只有表明它们接受类型为kMyCustomDragType的对象的对象才能接收到此丢弃。我终于返回YES表示我已成功将数据写入粘贴板。 (如果失败则返回NO

    如果你可以使用它,那么你可能已经获得了所需的所有拖放功能的90%。另外10%来自陌生人的要求。与往常一样,the documentation will be your best friend