2010-09-30 9 views
15

Tengo un UITableView al que agrego una fila con una animación (usando insertRowsAtIndexPaths:withRowAnimation:). Todo esto es bueno siempre que la tabla no sea más larga que la pantalla.UITableView desplácese hacia abajo para ver la animación de inserción

Si es más grande que la pantalla, entonces estoy tratando de desplazarme hacia la parte inferior, pero no está funcionando como quiero. Si me desplazo a la nueva fila después de que se agrega, extraño la animación. Si trato de desplazarme a ese indexPath antes de que se agregue, arroja una excepción (sobre que no es un indexPath válido)

¿Hay una solución a esto aparte de agregar una fila en blanco?

Respuesta

21

Sí, hay una solución sin agregar una fila en blanco.

Nota: En el código, considero que solo hay 1 sección pero muchas filas. Puede modificar el código para administrar varias secciones también.

- (void)theMethodInWhichYouInsertARowInTheTableView 
{ 
    //Add the object in the array which feeds the tableview 
    NSString *newStringObject = @"New Object"; 
    [arrayWhichFeeds addObject:newStringObject]; 

    [myTableView beginUpdates]; 

    NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1) inSection:0]]; 
    [myTableView insertRowsAtIndexPaths:paths withRowAnimation:NO]; 

    [myTableView endUpdates]; 
    [myTableView reloadData]; 
    [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
} 
+6

el segundo parámetro de '-insertRowsAtIndexPaths: withRowAnimation:' no es un 'BOOL'; es un tipo 'UITableViewRowAnimation' – user102008

+3

Todavía no veo la animación añadida con esta técnica. Se desplaza bien, pero incluso si paso un valor válido para withRowAnimation (no "NO", pero UITableViewRowAnimationFade) nunca lo veo suceder. La pregunta (creo) fue cómo desplazar y aún ver la animación de agregar (¿verdad?) – Aardvark

+0

Funciona muy bien si está utilizando 'UITableViewRowAnimation.Bottom' – zuziaka

3

Recuerde hacer esto en la rosca principal, de lo contrario, no se desplazará a la posición requerida.

20

Tuve este mismo problema. Aquí estaba mi solución.

Primera - Corrección de su fuente de datos

Segundo -

NSIndexPath *path = [NSIndexPath indexPathForRow:([arrayWhichFeeds count] - 1 inSection:0]]; 
NSArray *paths = [NSArray arrayWithObject:path]; 
[myTableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop]; 
[myTableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 

* Tenga en cuenta que esto no es envuelto en el código [tableView beginUpdades] y [tableView endUpdates]. Si lo haces, no funcionará como desees.

Pruébelo, debe animar en las nuevas filas desde la parte inferior mientras se desplaza hacia ellas.

+0

+1 para señalar que esto solo funciona cuando NO está incluido en beginUpdates & endUpdates . – ozz

+0

¡Funciona como un encanto! Perdí horas tratando de resolver esto. ¡Gracias! – Myxtic

+0

Sí, esto funciona, aunque tengo un poco de problema si inserto filas en la parte inferior de mi vista de tabla, luego permanecen fuera de la pantalla, pero de lo contrario estoy obteniendo el movimiento correcto. Buen punto sobre begin/endUpdates. Intenté allí primero y no funcionó. – Fraggle

1

De manera más general, para desplazarse hasta la parte inferior:

NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.table numberOfRowsInSection:([self.table numberOfSections] - 1)] - 1) inSection:([self.table numberOfSections] - 1)]; 
[self.table scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 
+0

Sí, pero desplazarse hacia abajo no es el problema. Necesito desplazarme de tal manera que la animación de inserción de la nueva fila sea visible. Creo que la respuesta de Applely es la solución correcta para esto. – Nathan

+0

Sí, estoy de acuerdo en que la respuesta de Applely es correcta. Sin embargo, si no quiere hacer suposiciones sobre la estructura de las filas/secciones de su tabla mientras aún puede desplazarse a la última fila, entonces mi código para scrollToRowAtIndexPath es más general y funcionaría muy bien combinado con la respuesta general de Applely. – djskinner

+0

Oh, vale, entiendo lo que quieres decir. ¡Gracias! – Nathan

6

Otras técnicas, como las mencionadas en esta pregunta no funcionó para mí. Esto sin embargo:

  1. Agregue el nuevo elemento a la colección interna de dataSource.
  2. Establezca un indicador en el elemento que indica que es "nuevo". Forzar la visualización de la celda para que no muestre nada cuando se establece esta bandera.
  3. llamada inmediatamente tableView: reloadData:
  4. Ahora es el nuevo elemento en esta tabla, pero aparecerá visualmente vacío (debido a la bandera).
  5. Compruebe si este nuevo elemento es visible usando tableView.indexPathsForVisibleRows.
  6. Si el elemento estaba en la pantalla, inmediatamente voltee ese indicador "nuevo" en el elemento de fuente de datos a NO y llame al tableView: reloadRowsAtIndexPaths con un conjunto de animación. Ahora aparecerá como si este artículo recién se hubiera agregado. (Ha terminado en este caso)
  7. Si no estaba en la pantalla desplácela a la vista con tableView: scrollToRowAtIndexPath: pero no llame inmediatamente a reloadRowsAtIndexPath ...
  8. Controle el mensaje (void) scrollViewDidEndScrollingAnimation, y hacer eso mismo reloadRowsAtIndexPath desde el paso 6. Sospecho que este método se llama desplazamiento en cualquier momento que ocurre, por lo que tendrá para detectar cuando se llama desde el paso 7 y cuando se llama a causa el usuario está desplazándose.

Trabajé esta técnica (y escribí esta respuesta) cuando comencé el desarrollo de iOS, pero esto funcionó a largo plazo.

0

Esto funciona para mí. En lugar de insertar una fila, simplemente la destaco (al desvanecerla). Sin embargo, el principio es el mismo.

if let definiteIndexPath = indexPathDelegate.getIndexPath(toDoItem) { 
    UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { 

     self.tableView.scrollToRowAtIndexPath(definiteIndexPath, atScrollPosition: .Middle, animated: false) 

     }, completion: { 
      (finished: Bool) -> Void in 

      // Once the scrolling is done fade the text out and back in. 
      UIView.animateWithDuration(5, delay: 1, options: .Repeat | .Autoreverse, animations: { 
       self.tableView.reloadRowsAtIndexPaths([definiteIndexPath], withRowAnimation: UITableViewRowAnimation.Fade) 

       }, completion: nil) 

    }) 

} 
0
  1. de actualización fuente de datos
  2. insertar una fila en la parte inferior
  3. Scroll a abajo

Ejemplo:

YOUR_ARRAY.append("new string")  
tableView.insertRows(at: [IndexPath(row: YOUR_ARRAY.count-1, section: 0)], with: .automatic) 
tableView.scrollToRow(at: IndexPath(row: YOUR_ARRAY.count-1, section: 0), at: UITableViewScrollPosition.bottom, animated: true) 
Cuestiones relacionadas