可以拖放文件URL文本,但不能拖放实际文件

时间:2012-07-14 14:35:59

标签: objective-c xcode macos cocoa

我可以从NSTableView单元格拖动文件URL并将其放在任何文本编辑器中。根据我对Apple文档的理解,当我删除URL时,应该将文件复制到放置位置。

- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard {

    //for now putting specific file path in just to get it working
    NSString *filePath = @"/Users/Jackh/Desktop/Apple.png";
    [pboard declareTypes:[NSArray arrayWithObject:NSURLPboardType] owner:self];
    [[NSURL URLWithString:filePath] writeToPasteboard:pboard];

    return YES;

}

如何将文件从filePath复制到删除的位置?它现在只是将filePath作为文本移动。

有什么想法吗?

修改:我现在正在使用此代码

-(void)awakeFromNib {

    [self.tableView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:NO];

}

...

[self.tableView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSFileContentsPboardType, nil]];

...

- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard {

    //for now putting specific file path in just to get it working
    NSString *filePath = @"/Users/Jackh/Desktop/Apple.png";
    [pboard declareTypes:[NSArray arrayWithObject:NSFileContentsPboardType] owner:nil];
    [pboard writeFileContents:filePath];

}

1 个答案:

答案 0 :(得分:4)

如果你想强制绿色“+”进行复制,只需在操作掩码中使用NSDragOperationCopy(仅限),禁止其他操作;例如在awakeFromNib

[self.tableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];

这是我能让你的例子与Finder一起使用的最好方法:

- (BOOL)
tableView:(NSTableView *)tv
writeRowsWithIndexes:(NSIndexSet*)rowIndexes
toPasteboard:(NSPasteboard*)pboard {
    NSString *filePath = @"/Users/kevin/Desktop/1.png";
    [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType]
                         owner:nil];
    [pboard setPropertyList:[NSArray arrayWithObject:filePath]
                            forType:NSFilenamesPboardType];
    return YES;
}

请注意,Apple建议使用更多现代API,但我发现在这种情况下它们会产生很大的副作用:它们似乎会导致文件被复制两次,因为URL以多种形式被神奇地复制。话虽如此,您的原始网址示例却无效,因为您应该在粘贴板上使用writeObjects:而不是将网址询问writeToPasteboard:。 URL的示例:

- (BOOL)
tableView:(NSTableView *)tv
writeRowsWithIndexes:(NSIndexSet*)rowIndexes
toPasteboard:(NSPasteboard*)pboard {
    NSString *filePath = @"/Users/kevin/Desktop/1.png";
    [pboard declareTypes:[NSArray arrayWithObject:NSURLPboardType]
                         owner:nil];
    [pboard writeObjects:[NSArray arrayWithObject:
                          [NSURL fileURLWithPath:filePath]]];
    return YES;
}

正如我在其他评论中提到的,如果你的拖动是针对文档而不是文件管理器(如Finder),那么最好包含文件的实际数据。原始数据不能被文档误解(即文档必须直接插入数据,它不能选择插入路径字符串)。另一方面,由于某种原因,原始数据拖拽不会在Finder中创建文件,因此它们主要用作将添加作为替代方法添加到粘贴板中。

这是一种使用UTI声明文件类型并调用NSData来读取文件的方法(我试过这个并且它可以工作,例如我可以将表格视图行拖到TextEdit中的Rich Text文档中并看到插入窗口的图像):

- (BOOL)
tableView:(NSTableView *)tv
writeRowsWithIndexes:(NSIndexSet*)rowIndexes
toPasteboard:(NSPasteboard*)pboard {
    NSString *filePath = @"/Users/kevin/Desktop/1.png";
    [pboard declareTypes:[NSArray arrayWithObject:@"public.png"]
                         owner:nil];
    [pboard setData:[NSData dataWithContentsOfFile:filePath]
                    forType:@"public.png"];
    return YES;
}

(我不知道为什么你的writeFileContents:不起作用,但上面的确有效,基本上是相同的。)