¿Cómo arrastrar UITableViewCell y soltarlo a otra UITableView?

Pude get solo una salida parcial, se logró la funcionalidad principal de drag and drop pero se bloqueó algunas veces y mostraba error como índice fuera de límites.

Utilizo el controller de gestos panorámico para drag and drop la celda UITableView, también quiero saber cómo se puede hacer al usar toques comenzados, toques movidos y toques terminados.

Este es mi código de muestra

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { pathNumber=indexPath.row; cell = [tableView cellForRowAtIndexPath:indexPath]; UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panDetected:)]; [cell addGestureRecognizer:panRecognizer]; if (cell.accessoryType==UITableViewCellAccessoryNone) { cell.accessoryType = UITableViewCellAccessoryCheckmark; if(tableView==tableView1) { [selectedCells addObject:[array objectAtIndex:indexPath.row]]; NSLog(@"indexpath-%d",indexPath.row); [arrayOfPaths addObject:indexPath]; NSLog(@"----%@",selectedCells); NSLog(@"----======%@",arrayOfPaths); } else { [selectedCells1 addObject:[array1 objectAtIndex:indexPath.row]]; NSLog(@"indexpath-%d",indexPath.row); [arrayOfPaths1 addObject:indexPath]; NSLog(@"====%@",selectedCells1); NSLog(@"----======]]]]]%@",arrayOfPaths1); } } else { cell.accessoryType = UITableViewCellAccessoryNone; if(tableView==tableView1) { [selectedCells removeObject:[array objectAtIndex:indexPath.row]]; [arrayOfPaths removeObject:indexPath]; NSLog(@"----%@",selectedCells); NSLog(@"----======remove%@",arrayOfPaths); } else { [selectedCells1 removeObject:[array1 objectAtIndex:indexPath.row]]; [arrayOfPaths1 removeObject:indexPath]; NSLog(@"====%@",selectedCells1); NSLog(@"----======remove1%@",arrayOfPaths1); } } } - (void)panDetected:(UIPanGestureRecognizer *)panRecognizer { CGPoint translation = [panRecognizer translationInView:self.view]; CGPoint cellViewPosition = cell.center; cellViewPosition.x += translation.x; cellViewPosition.y += translation.y; cell.center = cellViewPosition; [self.view bringSubviewToFront:cell]; [panRecognizer setTranslation:CGPointZero inView:self.view]; NSArray * arr=[NSArray arrayWithObject:[NSIndexPath indexPathForRow:pathNumber inSection:0]]; NSArray * arr1=[NSArray arrayWithObject:[NSIndexPath indexPathForRow:pathNumber inSection:0]]; if(panRecognizer.state==UIGestureRecognizerStateBegan) { position1=[panRecognizer locationInView:self.view]; } if(panRecognizer.state==UIGestureRecognizerStateEnded) { position = [panRecognizer locationInView:self.view]; NSLog(@"%f %f",position.x,position.y); if(CGRectContainsPoint(tableView2.frame, position)) { NSLog(@"1-2"); if(position.x>=tableView2.frame.origin.x && position1.x >= tableView1.frame.origin.x && position1.x <= tableView1.frame.size.width) { if([selectedCells count] ==1) { [tableView2 beginUpdates]; [tableView2 insertRowsAtIndexPaths:arr1 withRowAnimation:UITableViewRowAnimationTop]; [array1 insertObject:[array objectAtIndex:pathNumber] atIndex:pathNumber]; d=[array1 count]; [tableView2 endUpdates]; [tableView1 beginUpdates]; [tableView1 deleteRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationTop]; [array removeObjectAtIndex:pathNumber]; c=[array count]; [tableView1 endUpdates]; } else { [tableView2 beginUpdates]; [tableView2 insertRowsAtIndexPaths:arrayOfPaths withRowAnimation:UITableViewRowAnimationTop]; for(int j=0;j<[arrayOfPaths count];j++) { NSIndexPath * tempIndexPath = (NSIndexPath *)([arrayOfPaths objectAtIndex:j]); [array1 insertObject:[selectedCells objectAtIndex:j] atIndex:tempIndexPath.row]; } d=[array1 count]; NSLog(@"%d", d); [tableView2 endUpdates]; [tableView1 beginUpdates]; [tableView1 deleteRowsAtIndexPaths:arrayOfPaths withRowAnimation:UITableViewRowAnimationTop]; for(int j = 0;j < [arrayOfPaths count]; j++) { NSIndexPath * temp = (NSIndexPath *)[arrayOfPaths objectAtIndex:j]; [array removeObjectAtIndex:temp.row]; } c=[array count]; [tableView1 endUpdates]; } [selectedCells removeAllObjects]; [arrayOfPaths removeAllObjects]; } else { NSLog(@"else"); } } else if(CGRectContainsPoint(tableView1.frame, position)) { NSLog(@"hi-2"); if(position.x>=tableView1.frame.origin.x && position1.x >= tableView2.frame.origin.x && position1.x <= tableView2.frame.size.width + tableView2.frame.origin.x) { if([selectedCells1 count] == 1) { [tableView1 beginUpdates]; [tableView1 insertRowsAtIndexPaths:arr1 withRowAnimation:UITableViewRowAnimationTop]; [array insertObject:[array1 objectAtIndex:pathNumber] atIndex:pathNumber]; c=[array count]; [tableView1 endUpdates]; [tableView2 beginUpdates]; [tableView2 deleteRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationTop]; [array1 removeObjectAtIndex:pathNumber]; d=[array1 count]; [tableView2 endUpdates]; } else { [tableView1 beginUpdates]; [tableView1 insertRowsAtIndexPaths:arrayOfPaths1 withRowAnimation:UITableViewRowAnimationTop]; for(int j=0;j<[arrayOfPaths1 count];j++) { NSIndexPath * tempIndexPath = (NSIndexPath *)([arrayOfPaths1 objectAtIndex:j]); [array insertObject:[selectedCells1 objectAtIndex:j] atIndex:tempIndexPath.row]; } c=[array count]; NSLog(@"%d", c); [tableView1 endUpdates]; [tableView2 beginUpdates]; [tableView2 deleteRowsAtIndexPaths:arrayOfPaths1 withRowAnimation:UITableViewRowAnimationTop]; for(int j = 0;j < [arrayOfPaths1 count]; j++) { NSIndexPath * temp = (NSIndexPath *)[arrayOfPaths1 objectAtIndex:j]; [array1 removeObjectAtIndex:temp.row]; } d=[array1 count]; [tableView2 endUpdates]; } [selectedCells1 removeAllObjects]; [arrayOfPaths1 removeAllObjects]; } else { NSLog(@"else1"); } } } } 

Solutions Collecting From Web of "¿Cómo arrastrar UITableViewCell y soltarlo a otra UITableView?"

Puedes get la celda que estás tocando. Cuando tenga esa celda, puede almacenar sus valores en una celda temporal que debe declarar en su ".h", y eliminarlos de la fuente de datos de la primera tabla.

Cuando detecta que el toque ha finalizado, si ese toque terminó en una de las tablas, agregue la celda temporal a su dataSource y realice una reloadData. De lo contrario, si el toque no terminó en uno de los límites de las tablas, agregue celda temporal a la tabla original.

Para mejorar la funcionalidad visual, puede mostrar UITableViewCell en coorderadas táctiles.

Entonces, paso a paso:

  • En su ViewController declare: UITableviewCell * tempCell

  • Inicia "tempCell" en algún lugar de tu código con tempCell = [[UITableViewCell alloc]init]

  • Con ese método: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //Here you have selected row number; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //Here you have selected row number; } puede get la fila seleccionada, para que pueda recuperar los valores de celda de su fuente de datos. Almacene esos valores en "tempCell" y elimínelos de la fuente de datos de la tabla.

  • Puede agregar a ViewController.view UITableViewCell, si desea mostrar la celda mientras se toca.

  • Con - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; obtienes coorderadas táctiles. Con esas coorderadas, puedes verificar si están en una de tus tables. Si las coorderadas pertenecen a una de sus tablas, agregue a su dataSource, limpie "tempCell", (y elimine el cellView si se mostraba en la vista del ViewController) y finalmente haga [tableView reloadData]; . De lo contrario, si las coorderadas no pertenecen a sus tablas, agregue la celda a la fuente de datos original y limpie "tempCell".

Perdón por mi mal ingles 🙁

Puede hacer una instantánea a la celda y completar una vista de image. luego elimine la celda de la vista de tabla. agregue la vista de image a la vista de supervisión, anule los events táctiles o agregue un gesto panorámico cuando esté listo para soltar la vista de image de la instantánea, inserte la celda en la nueva vista de tabla y complete los datos