我必须在我的应用程序中使用NSTableViews显示存储为“CoreData”的数据。 TableViews非常基本,因为整个程序是。
右侧TableView显示清单列表,左侧显示此清单的内容。 现在我想允许用户将清单内的项目拖到另一个清单中。
我在网上找到了几个教程和示例代码,但是对于我对Cocoa的理解,它们是压倒性的。如果有人能够通过简短易懂的说明提及网页或教程等,那就太棒了。
非常感谢
编辑: 虽然很明显,我的应用程序是用Cocoa编写的,可以在Mac上运行。
答案 0 :(得分:27)
我有一个关于如何在我的下载页面上拖放使用NSOutlineView的小演示:http://davedelong.com/downloads它应该非常适用于NSTableView,因为NSOutlineView是NSTableView的子类。
这是对我在阅读文档大约一个月后学到的东西的5分钟升华。从NSTableViews拖放东西时,有三种“基本”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;
当有人将某些内容拖到您的NSTableView上时,会使用第一个tableView:acceptDrop:row:dropOperation:
。这很简单。有关丢弃的所有信息(包括被删除的内容)都可以在[info draggingPasteboard]
中找到。如果删除成功则返回YES
,否则返回NO
。
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。