来自基于视图的NSTableView的有前途的文件

时间:2012-10-12 03:55:23

标签: cocoa drag-and-drop nstableview appkit

我正在编写一个带有基于视图的表格视图的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拥有的窗口时,我正在拖动视图突出显示,表示它将接受拖动。

但是,当我删除图像时,不会创建任何文件。

为什么不能创建我承诺的内容的文件?

1 个答案:

答案 0 :(得分:3)

The documentation from the NSDraggingInfo protocol's namesOfPromisedFilesDroppedAtDestination: method给出了一个提示:

  

在此方法返回时,源可能已创建或未创建文件。

显然,至少在表格视图上下文中,这意味着“自己创建文件,你懒惰”。

我修改了我的表视图数据源的tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:方法,告诉每个拖动的模型对象将自己写入文件(由目标目录URL +模型对象的源URL中的文件名组成),并实现该功能在模型对象类中。现在一切都有效。