簡體   English   中英

從 NSTableView 拖放到 Finder 的問題

[英]Problem with Drag-Drop from NSTableView to Finder

我創建了一個應用程序,它有一個代表一系列文件的 NSTableView。 由此,我希望能夠將一行(即文件名)從我的 NSTableView 拖到 Finder,並在該文件夾中創建文件。 但是,我無法解決的是我需要修改原始文件的內容,然后才能將其復制到 Finder。

我添加了以下行,所以我可以拖到我的 NSTableView 之外:

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

如果我將當前文件位置添加到粘貼板,我可以讓它復制實際文件,使用:

- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
    [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];        
    NSMutableArray* dragfiles = [[NSMutableArray alloc] init];
    NSString* file = [self.files objectAtIndex:row];
    NSString* filepath = [[[self.pathControl URL] path] stringByAppendingPathComponent:file];
    [dragfiles addObject:filepath];
    [pboard setPropertyList:dragfiles forType: NSFilenamesPboardType];
    [dragfiles release];
} 

但是,因為我想修改文件的內容,我不想把文件路徑放到粘貼板上。 我試過使用 NSFileWrapper,但 Finder 似乎不接受這是一種有效的格式。

我檢查了谷歌,發現了一些建議,您可以創建一個臨時文件並使用該文件路徑。 但是,這感覺很難看。

是否可以將數據發送到 Finder? 有沒有辦法解決這個問題?

您很可能希望使用 promise 文件或NSFilesPromisePboardType而不是NSFilenamesPboardType (注意:promise 文件方法dragPromisedFilesOfTypes:fromRect:source:slideBack:event:namesOfPromisedFilesDroppedAtDestination:該文檔討論的是通用NSView方法NSTableView定義了更方便的方法,您將使用這些方法而不是通用方法。也就是說,這仍然應該提供有關 promise 文件拖動工作的信息)。 NSTableView使用tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes: ,您可以在其中處理文件。 在您的tableView:writeRowsWithIndexes:toPasteboard:方法中,您將聲明NSFilesPromisePboardType ,然后為您計划編寫的文件類型設置文件擴展名數組。 以下是概述了如何處理它的偽代碼:

- (BOOL)tableView:(NSTableView *)aTableView
     writeRowsWithIndexes:(NSIndexSet *)rowIndexes
        toPasteboard:(NSPasteboard *)pboard {
     [pboard declareTypes:[NSArray arrayWithObjects:NSFilesPromisePboardType, nil]];

     NSMutableArray *filenameExtensions = [NSMutableArray array];
     NSArray *draggedFilenames = [self.files objectsAtIndexes:rowIndexes];
     for (NSString *filename in draggedFilenames) {
          NSString *filenameExtension = [filename pathExtension];
          if (filenameExtension.length) {
              [filenameExtensions addObject:filenameExtension];
          }
     }
     [pboard setPropertyList:filenameExtensions
                 forType:NSFilesPromisePboardType];
     return YES;
}

然后在您的 names-of-promisedFiles 方法中:

- (NSArray *)tableView:(NSTableView *)aTableView
       namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
       forDraggedRowsWithIndexes:(NSIndexSet *)indexSet {

     NSArray *draggedFilenames = [self.files objectsAtIndexes:indexSet];

     for (NSString *filename in draggedFilenames) {
           // do your processing of files in here
          // if it may take a long time, you might need to do it on a background
          // thread

         NSString *fullPathToOriginal = nil;
          NSString *destPath =
         [[dropDestination path] stringByAppendingPathComponent:filename];


     }
     return draggedFilenames;
}

您應該能夠計算原始文件路徑(不確定您如何確定它,所以我在上面的代碼中將其保留為nil )和目標文件路徑(使用類似於上面代碼中的內容)。

有什么要注意的。

NSPasteboard.h中有一條評論說:

/* Use of pboard types should be replaced with use of UTIs.  
   Pboard types will be deprecated in a future release. */

NSFilesPromisePboardType定義之后說:

// Use (NSString *)kPasteboardTypeFileURLPromise

我只是花了幾個小時把頭撞在磚牆上,因為我在幾個地方傳遞了(NSString *)kPasteboardTypeFileURLPromise而不是NSFilesPromisePboardType

看起來他們做的事情不太一樣。 我不知道為什么:

tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes 

沒有被調用。 當我切換回NSFilesPromisePboardType時,
突然它被調用了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM