问题
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;
}
来源:https://stackoverflow.com/questions/24678189/understand-drop-in-nstableview