了解NStableView中的drop

时间:2014-07-10 13:44:36

标签: drag-and-drop datasource nstableview

我在IB中有一个带有数据源和绑定的NStableview。 DataSource对象从NSOpenPanel Action获取它们的值。然后,一个函数从openPanel接收URLS,并做好脏工作。 所以,我要实现的是通过Drag操作提供openPanel的替代方案。真诚地,我需要告诉我,我没有相当多的拖放技巧,在阅读和阅读有关它的文档之后,仍然有几个飞在我的手中....目前我可以放入文件tableview,接收文件url corrctly,在datasorce数组中加载值,但我不能把行放在tableview中。重复我想通过拖动替代openPanel,所以任何建议都很受欢迎。谢谢,对不起长代码

我的代码:

//step 1
- (void)awakeFromNib {    
  [_tableView registerForDraggedTypes:[NSArray arrayWithObject:(NSURL*)kUTTypeFileURL]];
}

//2
- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes     toPasteboard:(NSPasteboard*)pboard
{
NSLog(@"write rows with indexes"); // no log output
return YES;
}
 //3
- (NSDragOperation)tableView:(NSTableView *)_tableView validateDrop:(id < NSDraggingInfo >)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation
{
  //get the file URLs from the pasteboard
NSPasteboard* pb = info.draggingPasteboard;

//list the file type UTIs we want to accept
NSArray* acceptedTypes = [NSArray arrayWithObject:(NSString*)kUTTypeMP3];

NSArray* urls = [pb readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]]
                                  options:[NSDictionary dictionaryWithObjectsAndKeys:
                                           [NSNumber numberWithBool:YES],NSPasteboardURLReadingFileURLsOnlyKey,
                                           acceptedTypes,   NSPasteboardURLReadingContentsConformToTypesKey,
                                           nil]];

//only allow drag if there is exactly one file
if(urls.count != 1)
return NSDragOperationNone;

NSLog(@"ArrayDrag is %@", [urls description]);
NSLog(@"ArrayDrag is %lu", (unsigned long)[urls count]);

if ( [[pb types] containsObject:NSURLPboardType] ) {

NSURL *fileURL = [NSURL URLFromPasteboard:pb];
NSLog(@"fileURL Drop %@", fileURL); // url log OK!!!

// [self audioSetup:fileURL]; // function audioSetup receive the url ok.

}


return NSDragOperationCopy; // how to deal this return?
}


- (BOOL)tableView:(NSTableView *)_tableView acceptDrop:(id < NSDraggingInfo >)info    row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation {

 //Get the files from the drop
 NSArray * files = [[info draggingPasteboard] propertyListForType:NSURLPboardType];

 NSLog(@"FILES files is: %@", files);
 NSLog(@"FILES COUNT is: %lu", (unsigned long)files.count); // Count return is 2! ?

 NSLog(@"FILES INDEX 0 is: %@", [files objectAtIndex:0]); // is right url
 NSLog(@"FILES INDEX 1 is: %@", [files objectAtIndex:1]); // is "" ?!?

 NSURL *urlFromBP = [files objectAtIndex:0]; // 
 [self audioSetup:urlFromBP];

 NSLog(@"FILES 2 files is: %@", [files description]);    

 if([files count] > 0) return YES;
 return NO;
 }

//此时似乎没问题,但在电视中拖动文件后我得到了这个......

FILES COUNT is: 2
2014-07-10 14:18:46.339 ToolSet[1618:303] FILES INDEX 0 is: file:///Users/s...x/Desktop /NUOVE%20TRAXSOURCE /Boston%20Rodriguez,%20Cherie%20Mathieson%20-%20Lost%20in%20Space%20(DJ%20Spinna%20Galactic%20Soul%20    Remix).mp3
2014-07-10 14:18:46.339 ToolSet[1618:303] FILES INDEX 1 is: 

2014-07-10 14:18:46.340 ToolSet[1618:303] myAudioUrl is: (
"file:///Users/s....x/Desktop/NUOVE%20TRAXSOURCE /Boston%20Rodriguez,%20Cherie%20Mathieson%20-%20Lost%20in%20Space%20(DJ%20Spinna%20Galactic%20Soul%20     Remix).mp3"
 )
2014-07-10 14:18:46.340 ToolSet[1618:303] myAudioUrl CouNt: 1
2014-07-10 14:18:46.340 ToolSet[1618:303] tuuti gli audioURL0: file:///Users/s.....x/Desktop /NUOVE%20TRAXSOURCE  /Boston%20Rodriguez,%20Cherie%20Mathieson%20-%20Lost%20in%20Space%20(DJ%20Spinna%20Galactic%20Soul%20    Remix).mp3

Up to here everything seems to be fine

2014-07-10 14:18:46.341 ToolSet[1618:303] -[__NSCFString baseURL]: unrecognized selector sent to  instance 0x600000148140
2014-07-10 14:18:46.341 ToolSet[1618:303] *** Canceling drag because exception   'NSInvalidArgumentException' (reason '-[__NSCFString baseURL]: unrecognized selector sent to     instance 0x600000148140') was raised during a dragging session

请我从哪里了解两个错误!

1 个答案:

答案 0 :(得分:0)

经过深入调查,我找到了实现我的方向的正确方向。注意:删除URL只允许一次拖动一个文件。

// declare registerForDraggedTypes

- (void)awakeFromNib {
[_tableView registerForDraggedTypes:[NSArray arrayWithObject:(NSURL*)kUTTypeFileURL]];
}

// method for readableTypesForPasteboard

+ (NSArray*)
readableTypesForPasteboard: (NSPasteboard*) inPasteboard
{
static NSArray* types = nil;
if (types == nil)
{
    types = [NSArray arrayWithObjects: [NSArray arrayWithObject:(NSURL*)kUTTypeFileURL], nil];
}

return types;
}

// Boolean method

- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes   toPasteboard:(NSPasteboard*)pboard
{
NSLog(@"write rows with indexes");
return YES;
}

//Validate drop in TV

- (NSDragOperation)tableView:(NSTableView *)_tableView validateDrop:(id < NSDraggingInfo >)info  proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation
{
//get the file URLs from the pasteboard
NSPasteboard* pb = info.draggingPasteboard;

//list the file type UTIs we want to accept
NSArray* acceptedTypes = [NSArray arrayWithObject:(NSString*)kUTTypeMP3];

NSArray* urls = [pb readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]]
                                  options:[NSDictionary dictionaryWithObjectsAndKeys:
                                           [NSNumber numberWithBool:YES],NSPasteboardURLReadingFileURLsOnlyKey,
                                           acceptedTypes, NSPasteboardURLReadingContentsConformToTypesKey,
                                           nil]];

//only allow drag if there is exactly one file
if(urls.count != 1)

    //if(urls.count != 1)
    return NSDragOperationNone;

NSLog(@"ArrayDrag is %@", [urls description]);
NSLog(@"ArrayDrag is %lu", (unsigned long)[urls count]);

if ( [[pb types] containsObject:NSURLPboardType] ) {

    NSURL *fileURL = [NSURL URLFromPasteboard:pb];
    NSLog(@"fileURL Drop %@", fileURL);

}

return NSDragOperationCopy;
}

// Accept drop in TV

- (BOOL)tableView:(NSTableView *)_tableView acceptDrop:(id < NSDraggingInfo >)info  row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation {
NSPasteboard *pboard = [info draggingPasteboard];

if ( [[pboard types] containsObject:NSURLPboardType] ) {

    NSURL *fileURL = [NSURL URLFromPasteboard:pboard];

    NSLog(@"fileurl in PASTEBOARD %@", fileURL);
    [self getURLfromPb:fileURL];

}

return YES;

if([files count] > 0) return YES;

return NO;

}