我正在编写一个带有基于视图的表格视图的Mac应用程序。这是一个图像列表,我打算让用户能够拖动到Finder将每个图像保存到文件中。
数据源拥有一组自定义模型对象。模型对象都符合NSPasteboardWriting
协议,如下所示:
- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard { //self.screenshotImageDataType is set after the image is downloaded, by examining the data with a CGImageSource. //I have verified that it is correct at this point. Its value in my test was @"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)) { return self.screenshotImageData; } else if (UTTypeEqual((__bridge CFStringRef)type, kUTTypeURL)) { return [self.screenshotImageURL pasteboardPropertyListForType:type]; } else if (UTTypeEqual((__bridge CFStringRef)type, kPasteboardTypeFilePromiseContent)) { return self.screenshotImageDataType; } id plist = [self.screenshotImage pasteboardPropertyListForType:type] ?: [self.screenshotImageURL pasteboardPropertyListForType:type]; NSLog(@"plist for type %@: %@ %p", type, [plist className], plist); return [self.screenshotImage pasteboardPropertyListForType:type] ?: [self.screenshotImageURL pasteboardPropertyListForType:type]; }
我的对象拥有的URL是Web URL,而不是本地文件。它们是从中下载图像的URL。
表视图的data-source-and-delegate-in-one实现了与文件承诺相关的方法:
- (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拥有的窗口时,我正在拖动视图突出显示,表示它将接受拖动。
但是,当我删除图像时,不会创建任何文件。
为什么不能创建我承诺的内容的文件?
答案 0 :(得分:3)
在此方法返回时,源可能已创建或未创建文件。
显然,至少在表格视图上下文中,这意味着“自己创建文件,你懒惰”。
我修改了我的表视图数据源的tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:
方法,告诉每个拖动的模型对象将自己写入文件(由目标目录URL +模型对象的源URL中的文件名组成),并实现该功能在模型对象类中。现在一切都有效。