【发布时间】:2012-10-12 03:55:23
【问题描述】:
我正在编写一个带有基于视图的表格视图的 Mac 应用程序。这是一个图像列表,我希望用户能够将其拖到 Finder 以将每个图像保存到文件中。
数据源拥有一组自定义模型对象。模型对象都符合NSPasteboardWriting协议,如下:
- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard {
//self.screenshotImageDataType 在图像下载后设置,通过使用 CGImageSource 检查数据。
//我已经验证了此时它是正确的。它在我的测试中的值是@"public.jpeg" (kUTTypeJPEG)。
return @[ self.screenshotImageDataType, (__bridge NSString *)kUTTypeURL, (__bridge NSString *)kPasteboardTypeFilePromiseContent ];
}
- (id)pasteboardPropertyListForType:(NSString *)type {
if (UTTypeEqual((__bridge CFStringRef)type, (__bridge CFStringRef)self.screenshotImageDataType)) {
返回self.screenshotImageData;
} else if (UTTypeEqual((__bridge CFStringRef)type, kUTTypeURL)) {
返回 [self.screenshotImageURL pasteboardPropertyListForType:type];
} else if (UTTypeEqual((__bridge CFStringRef)type, kPasteboardTypeFilePromiseContent)) {
返回self.screenshotImageDataType;
}
id plist = [self.screenshotImage pasteboardPropertyListForType:type]
?: [self.screenshotImageURL pasteboardPropertyListForType:type];
NSLog(@"plist for type %@: %@ %p", type, [plist className], plist);
返回 [self.screenshotImage pasteboardPropertyListForType:type]
?: [self.screenshotImageURL pasteboardPropertyListForType:type];
}
我的对象拥有的 URL 是 Web URL,而不是本地文件。它们是下载图像的 URL。
table view 的 data-source-and-delegate-in-one 实现了一个与文件 promise 相关的方法:
- (NSArray *)tableView:(NSTableView *)tableView
namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestinationURL
forDraggedRowsWithIndexes:(NSIndexSet *)rows
{
return [[self.screenshots objectsAtIndexes:rows] valueForKeyPath:@"screenshotImageURL.lastPathComponent"];
}
记录该表达式的值会生成具有正确文件扩展名的有效文件名。
最后,在windowDidLoad 中,我发送了一条消息,开启了这一切:
//Enable copy drags to non-local destinations (i.e., other apps).
[self.tableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];
舞台已经搭建好了。以下是窗帘拉起时会发生的情况:
当我拖动到 Finder 拥有的窗口时,我拖动到的视图会突出显示,表明它将接受拖动。
但是,当我删除图像时,不会创建任何文件。
为什么我承诺的内容没有创建?
【问题讨论】:
标签: cocoa drag-and-drop nstableview appkit