0

我可以从 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];

}
4

1 回答 1

4

如果要强制绿色的“+”复制,只需要NSDragOperationCopy在操作掩码中使用(only)即可,不允许其他操作;例如在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 被神奇地以多种形式复制。话虽如此,您的原始 URL 示例不起作用,因为您应该writeObjects:在粘贴板上使用而不是询问 URL 到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 中的富文本文档中,并查看插入到窗口中的图像):

- (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:不工作,但上面的工作,基本上是一样的。)

于 2012-07-15T02:43:15.920 回答