2012-09-20 25 views
17

Esta mañana acabo de instalar nuevo Xcode que incluye iOS 6.iOS UITableView scrollToRowAtIndexPath no funciona más

tengo una vista de tabla cargada con un archivo plist contiene capítulos y líneas. Los capítulos definen las secciones.

El usuario selecciona el capítulo y la línea, y la vista de tabla se desplaza automáticamente a la posición correcta (en viewDidLoad).

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:linePos inSection:chapterPos]; 
[self.tableView scrollToRowAtIndexPath:indexPath 
    atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

esto funciona muy bien en el simulador iOS5.

Al probar esto en el simulador iOS 6, el desplazamiento no se realiza. No obtengo errores He verificado, linePos y chapterPos reciben los valores correctos, pero el desplazamiento no se realiza.

¿Alguna idea de por qué?

+4

solo para aumentar el dolor y la miseria se rompe nuevamente 5 años después en iOS 11. –

Respuesta

26

Para versiones recientes de iOS, lea la respuesta de Fyodor Volchyok. Tenga en cuenta que no está marcado como la respuesta aceptada simplemente porque en el momento en que se realizó la pregunta por primera vez (septiembre de 2012), la respuesta actual fue la solución de trabajo. Las versiones más recientes de iOS también tienen el mismo problema que ahora se resuelve con la respuesta de Fyodor Volchyok, por lo que debe hacer +1 en su respuesta en ese momento.


Encontré la respuesta. Tengo que recargar primero los datos en el tableview

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:linePos inSection:chapterPos]; 

[self.tableView reloadData]; 

[self.tableView scrollToRowAtIndexPath:indexPath 
    atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

A pesar de que he encontrado la respuesta no sé por qué se está trabajando en IOS5 y no en iOS6.

EDITAR

tal vez debería añadir que a pesar de que estaba trabajando, todavía estaba teniendo un problema en la visualización de la última fila y publicado una pregunta para que

UItableview scrollToRowAtIndexPath not displaying last row correctly

Como @ Raj también lo pidió, debería decir que lo estaba desencadenando en el viewDidLoad. Para corregir el problema de la última fila que no se visualizaba correctamente, tuve que ponerlo en el viewDidAppear.

+0

Gracias por esta información, me encontré con lo mismo. También noté que no anima el desplazamiento de la tabla, solo lo muestra en la fila seleccionada. –

+0

¿Está activando la llamada scrollToRowAtIndexPath en su método -viewDidLoad? –

40

Objective-C

[self.tableView reloadData]; 
dispatch_async(dispatch_get_main_queue(), ^{ 
     NSIndexPath *rowIndexPath = [NSIndexPath indexPathForRow:3 inSection:0]; 
     [self.tableView scrollToRowAtIndexPath:rowIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; 
}); 

Swift

tableView.reloadData() 
DispatchQueue.main.async { 
    let indexPath = IndexPath(row: linePos, section: chapterPos) 
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true) 
} 
+0

Es una solución importante, sin esto la aplicación podría fallar accidentalmente, dependiendo de los procesos reloadData. – BootMaker

+3

esto es lo único que funciona para mí (iOS 9.1). El 'scrollToRowAtIndexPath' siempre falló al desplazarse a la celda inferior a menos que lo envolviera en' dispatch_async (dispatch_get_main_queue(), {...} 'aunque' scrolltoRowAtIndexPath' ya estaba siendo llamado desde el hilo principal. –

+0

Esta es probablemente la respuesta correcta , MÁS poner esto en el viewDidAppear: –

1

Después iOS7 la propiedad automaticallyAdjustsScrollViewInsets de incumplimiento UIViewController es YES. Hará que el sistema ajuste el contentOffset de tableView cuando el controlador de vista presiona. Incluso usted llama al [self.tableView scrollToRowAtIndexPath:rowIndexPath atScrollPosition:UITableViewScrollPositionNone animated:NO]; en el viewWillAppear. El contentOffset también será cambiado por el sistema después de viewWillAppear. Entonces mi solución es:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.automaticallyAdjustsScrollViewInsets = NO; 

    /// any other codes 
} 

- (void)viewWillLayoutSubviews { 
    self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 0, 0); 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    // change tableView data source 

    [self.tableView reloadData]; 
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.dataSourceArray count] - 1 inSection:0]; 
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO]; 
} 
0

Estoy agregando esta respuesta como una adición a la respuesta de Fyodor Volchyok. También encontré que el envío resuelve el problema. Pude encontrar una solución que no despacha.

self.tableView.reloadData() 
let index = // the desired index path 

// For some reason, requesting the cell prior to 
// scrolling was enough to workaround the issue. 
self.tableView.cellForRowAtIndexPath(index) 

self.tableView.scrollToRowAtIndexPath(index, atScrollPosition: .Top, animated: false) 
+0

Tuve un problema con multihilo: cuando uso dispatch, uno de mis métodos comienza a llamar dos veces. ¡Y ahora funciona como magia! :-) –

0
respuesta de

Fyodor Volchyok en Swift:

tableView.reloadData() 
let indexPath = NSIndexPath(forRow: linePos, inSection: chapterPos) 
// make sure the scroll is done after data reload was finished 
dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true) 
} 
0

que trabajó para mí en ios11

self.tableView.estimatedRowHeight = 0; 
self.tableView.estimatedSectionFooterHeight = 0; 
self.tableView.estimatedSectionHeaderHeight = 0 

dispatch_async(dispatch_get_main_queue(), ^{ 
    NSInteger numberOfSections = self.tableView.numberOfSections; 
    if (numberOfSections > 0) 
    { 
    NSInteger lastSection = numberOfSections - 1; 
    NSInteger lastRowInLastSections = [self.tableView numberOfRowsInSection:lastSection] - 1; 

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastRowInLastSections inSection:lastSection]; 
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:isAnimated]; 
} 
}); 
1

me encontré con otro tema (probablemente un error) con scrollToRowAtIndexPath específicamente en un iPhone X corriendo ios11. Mi tabla tiene cientos de secciones y en modo colapsado ~ 10 caben en la pantalla visible. A medida que indexPath se hizo más profundo, el desplazamiento gradualmente se retrasó.

Por ejemplo, cuando quería buscar el artículo en la fila 30, ScrollPositionTop tenía una fila adicional antes de la fila real que esperaba estar en la parte superior.

Y mientras probé buscando filas más profundas, comenzó a quedarse atrás aún más cuando, por decir algo más allá de 100 filas de profundidad, la fila esperada ni siquiera llegaba al área visible.

La solución que encontré hasta ahora es decir animada: NO para el desplazamiento dentro de dispatch_async, entonces funciona sin problemas técnicos.

Cuestiones relacionadas