Understand drop in NStableView

2019-09-01 04:01发布

问题:

I have a NStableview with datasource and bindings in IB. DataSource object get they value from NSOpenPanel Action. Then, a function receive URLS from openPanel, and do the dirty work very well. So, what i would achieve is offer an alternative to openPanel via Drag operation. Sincerely i need to tell that i don't have quite skill about drag and drop, and after read and read documentation about it, still have o couple of fly in my hand.... At the moment i can drop file in tableview, receive the file url corrctly, load value in datasorce array, but i can't put row in tableview. Repeat i would like achive via drag an alternative to openPanel so any suggestion is largely appreciated. thank you and sorry for long code

my code:

//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;
 }

//at this point it seems ok but after dragged a file in TV i get this...

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

please i need to understand from where come the two error!

回答1:

After a deep investigation i have found the right direction for achieve my gol. Note: Drop URL allow drag only one file at time.

// 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;

}