objective-c cocoa drag-and-drop nstableview

objective c - Implementando arrastrar y soltar en NSTableView



objective-c cocoa (7)

Debe declarar un tipo de arrastre personalizado para su vista de tabla y luego llamar a registerForDraggedTypes: con su tipo personalizado. De lo contrario, como habrás notado, ninguno de estos métodos será llamado.

¿Alguien puede ayudarme a implementar arrastrar y soltar en un NSTableView? Usé este código a continuación, pero estos métodos no se llaman durante la ejecución.

- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard { // Copy the row numbers to the pasteboard. NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; [pboard declareTypes:[NSArray arrayWithObject:@".gif"] owner:self]; [pboard setData:data forType:@".gif"]; return YES; } - (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)op { // Add code here to validate the drop if (row > [ m_imageArray count]) return NSDragOperationNone; if (nil == [info draggingSource]) // From other application { return NSDragOperationNone; } else if (self == [info draggingSource]) // From self { return NSDragOperationNone; } else // From other documents { [tv setDropRow: row dropOperation: NSTableViewDropAbove]; return NSDragOperationCopy; } NSLog(@"validate Drop"); return NSDragOperationCopy; } - (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation { NSPasteboard* pboard = [info draggingPasteboard]; NSData* rowData = [pboard dataForType:@".gif"]; NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData]; NSInteger dragRow = [rowIndexes firstIndex]; // Move the specified row to its new location... }


Puede registrarse para draggedTypes para un NSMutableArray o NSMutableDictionary o cualquier otro objeto. El siguiente fragmento de código es para un NSMutableArray.

[tableView registerForDraggedTypes:[NSArray arrayWithObject:@"NSMutableArray"] ];


awakFromnib declarar un método registerForDraggedTypes en awakFromnib

Me gusta esto.

[table_view registerForDraggedTypes:[NSArray arrayWithObjects:BasicTableViewDragAndDropDataType, nil]];


Tengo que recomendar tanto esta excelente publicación de blog Red Sweater

http://www.red-sweater.com/blog/274/a-moveable-beast

Proporciona una subclase NSArrayController que permitirá arrastrar y soltar el reordenamiento de los elementos de la tabla, y si desea soportar el arrastre fuera de la vista de tabla con sus objetos, acabamos de escribir una adición clara y sencilla a esa clase:

http://www.rwe-uk.com/blog/comments/nstableview_drag_and_drop_with_bindings_and_nsarraycontroller

Se basa en la publicación original


Normalmente observo este tipo de error cuando olvidé conectar el dataSource al NSTabeView en IB, es decir, la clase que implementa el tableView:writeRowsWithIndexes:toPasteboard: del NSTableViewDataSource .


Aquí hay un ejemplo

#import "TableViewController.h" #import "Person.h" #define MyDataType @"MyDataType" @implementation TableViewController { NSMutableArray *list; NSInteger sourceIndex; } @synthesize tableView; -(void)awakeFromNib { [tableView registerForDraggedTypes:[NSArray arrayWithObjects:MyDataType, nil]]; list = [[NSMutableArray alloc] init]; Person *person = [[Person alloc] initWithName:@"Newton" age:64]; [list addObject:person]; person = [[Person alloc] initWithName:@"Archimedes" age:74]; [list addObject:person]; person = [[Person alloc] initWithName:@"Euler" age:44]; [list addObject:person]; person = [[Person alloc] initWithName:@"Poincare" age:24]; [list addObject:person]; person = [[Person alloc] initWithName:@"Gauss" age:34]; [list addObject:person]; } -(void)reArrange:(NSMutableArray *)array sourceNum:(NSInteger)sourceNum destNum:(NSInteger)destNum { Person *person = list[sourceNum]; [list insertObject:person atIndex:destNum]; if (sourceNum < destNum) { [list removeObjectAtIndex:sourceNum]; } else { [list removeObjectAtIndex:sourceNum+1]; } [tableView reloadData]; } #pragma mark - Table // how many rows are there in the table? -(NSInteger)numberOfRowsInTableView:(NSTableView *)tv { return list.count; } // What object should I show in a particular cell? -(id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { Person *person = list[row]; NSString *identifier = [tableColumn identifier]; return [person valueForKey:identifier]; } // Should I accept the drag with the rows specified by rowIndexes? If YES then place the data on the provided paste board. - (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; [pboard declareTypes:[NSArray arrayWithObject:MyDataType] owner:self]; [pboard setData:data forType:MyDataType]; sourceIndex = [rowIndexes firstIndex]; return YES; } // What kind of drag operation should I perform? - (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)op { return op == NSTableViewDropAbove; // Specifies that the drop should occur above the specified row. } // The mouse button was released over a row in the table view, should I accept the drop? - (BOOL)tableView:(NSTableView*)tv acceptDrop:(id )info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)op { [self reArrange:list sourceNum:sourceIndex destNum:row]; // let the source array reflect the change return YES; } @end


Arrastra y suelta NSTableview usando datos básicos

  1. Registre el objeto de vista de tabla para arrastrar y soltar: -

    [tblCategory registerForDraggedTypes:[NSArray arrayWithObject:@"public.text"]];

Arrastra y suelta los métodos de delegado: -

- (id <NSPasteboardWriting>)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row { Category *category = (Category *)[self.arrCategoryList objectAtIndex:row]; NSString *identifier = category.categoryname; NSPasteboardItem *pboardItem = [[NSPasteboardItem alloc] init]; [pboardItem setString:identifier forType: @"public.text"]; return pboardItem; } - (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation { if(dropOperation == NSTableViewDropOn) { NSPasteboard *p = [info draggingPasteboard]; NSString *title = [p stringForType:@"public.text"]; Category* category ; NSInteger srcIndex; for (srcIndex = 0; srcIndex < [_arrCategoryList count]; srcIndex++) { category = [_arrCategoryList objectAtIndex:srcIndex]; if ([category.categoryname isEqualToString:title]) { break; } category = nil; } if(!category) { // Not found return NO; } [_arrCategoryList removeObjectAtIndex:srcIndex]; [_arrCategoryList insertObject:category atIndex:row]; [tblCategory reloadData]; return NSDragOperationMove; } return NSDragOperationNone; } - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation { return YES; }