我正在编写一个带有基于视图的表格视图的 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 拥有的窗口时,我拖动到的视图会突出显示,表明它将接受拖动。
但是,当我删除图像时,不会创建任何文件。
为什么我承诺的内容没有被创建?