2009-09-26 26 views
19

Estoy tratando de hacer que mi vista de tabla recuerde su última posición, de modo que después de que la aplicación se ejecute nuevamente, se desplazará a esa posición. para hacer esto, en mi método viewWillDisappear:, obtengo el primer número de fila visible y lo guardo en NSUserDefaults. entonces en mi viewDidAppear trato de desplazarme a esa fila enviando scrollToRowAtIndexPath a la vista de tabla. Sin embargo consigo un NSRangeException:UITableView scrollToRowAtIndexPath

*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:]: section (0) beyond bounds (0).

cualquier ayuda apreciada. Aquí está el código:

- (void)viewDidAppear:(BOOL)animated 
{ 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 

    if ([userDefaults valueForKey:@"content_row"] != nil) 
    { 
     int rowToHighlight = [[userDefaults valueForKey:@"content_row"] intValue]; 
     NSIndexPath * ndxPath= [NSIndexPath indexPathForRow:rowToHighlight inSection:0]; 
     [contentTableView scrollToRowAtIndexPath:ndxPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    } 
} 

-(void) viewWillDisappear:(BOOL)animated 
{ 
    NSIndexPath *selectedRowPath = [[contentTableView indexPathsForVisibleRows] objectAtIndex:0]; 
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
    [userDefaults setInteger:selectedRowPath.row forKey:@"content_row"]; 
} 
+0

¿Podría publicar el bit de código que hace la creación scrollToRowAtIndexPath y NSIndexPath? – probablyCorey

Respuesta

52

Recargar tablaVer datos antes de llamar a scrollToRowAtIndexPath.

[contentTableView reloadData]; 
+4

Esto no funciona para mí cuando los datos aún no están cargados (usando un controlador de resultados obtenido). Mi solución fue comprobar 'tableView.numberOfRowsInSection (0)> 0' primero. – SimplGy

+0

o si está en un hilo diferente, intente esto. '[tblView performSelectorOnMainThread: @selector (reloadData) withObject: nil waitUntilDone: YES]' – matrixugly

8

Es posible que contentTableView aún no haya terminado de cargar los datos.

+1

¿Cómo me notifican cuando termina? –

+2

Lo siento, pensé que el scrollToRowAtIndexPath se llamaba en viewDidLoad. Tengo llamadas similares en viewDidAppear, pero en lugar de regresar a un número de fila guardado, regreso a un valor de clave guardado que se guarda en didSelectRowAtIndexPath. Antes de llamar a scrollToRowAtIndexPath, encuentro la fila del valor clave en la fuente de datos cargada actualmente. – DyingCactus

+0

¡Dulce! Esto realmente ayudó a que mis engranajes giraran en la dirección correcta. Elaboré en una respuesta separada. – matrixugly

0

Quiero dar más detalles sobre la respuesta de DyingCactus. No soy bastante nuevo desarrollador de iOS y mi situación era un poco diferente, pero como dijo

"Es posible que el contentTableView aún no ha terminado de cargar los datos"

Mientras que la respuesta fue breve, hizo que mis ruedas giraran y fue exactamente lo que estaba sucediendo para mí.

mi configuración

  • UITableView está en ViewController "A"
  • Mi aplicación presenta una nueva "B" ViewController
  • En ViewController "B" se hace clic en un botón, a continuación, se añade los datos a la fuente de datos para UITableView.
  • desde el manejador de clic de botón de B, [tableView reloadData] se llama
  • desde el manejador de clic de botón de B, [tableView selectRowAtIndexPath:idxPath animated:false scrollPosition:UITableViewScrollPositionTop]; se llama
  • ViewController "B" es despedido y "A" se presenta de nuevo (que muestra la UITableView actualizada)

Solución

  • El primer problema que tenía que resolver era llamar reloadData en el hilo principal como

    [tblView performSelectorOnMainThread: @selector (reloadData) withObject: nil waitUntilDone: false];

  • El último problema fue cambiar waitUntilDone a true (DUH!)

Sí, por lo que, obviamente, para mí, la contentTableView no había terminado de cargar los datos, ya que mi llamada reloadData que está siendo ejecutado en el hilo principal no se ha establecido explícitamente para bloquear hasta que se realiza el selector.

Espero que esto ayude a alguien.

Cuestiones relacionadas