2010-05-28 8 views
9

Se coloca una vista con una tabla en la pantalla y quiero que se desplace hasta cierta fila en la tabla antes de que realmente se muestre la pantalla. Uso este código dentro del controlador de vista final.Desplácese inmediatamente a la fila en la tabla antes de ver la vista

NSIndexPath *scrollToPath = [NSIndexPath indexPathForRow:5 inSection:0]; 
[theTable scrollToRowAtIndexPath:scrollToPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

Cuando lo puse en el método viewDiDAppear, entonces parpadea brevemente desde la posición intial de la mesa (en la parte superior) a la fila que quiero. No quiero que muestre la posición inicial. Si lo pongo en viewDidLoad o viewWillAppear, se bloquea con una NSRangeException, presumiblemente porque la tabla aún no está configurada.

¿Cómo hago para que se desplace sin mostrar la posición inicial?

+1

[Esto] (http://stackoverflow.com/questions/2289114/make-uitableview-selection-before-view-appears/2289812#2289812) y [esta] (http: // stackoverflow. com/questions/2156614/how-to-start-uitableview-on-the-last-cell) podría ayudar. – DyingCactus

Respuesta

13

Gracias a Shaggy y moribundo Cactus para mí apuntando en la dirección correcta. La respuesta es cargar la mesa y de desplazamiento en viewWillAppear:

-(void)viewWillAppear:(BOOL)animated 
{ 
    [theTable reloadData]; 
    NSIndexPath *scrollToPath = [NSIndexPath indexPathForRow:5 inSection:0]; 
    [theTable scrollToRowAtIndexPath:scrollToPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
} 
+1

Asegúrese de marcar su propia respuesta como aceptada para que otros que lean esta pregunta puedan verla de un vistazo :) – BoltClock

+0

Esto es genial para lo que necesitaba. Lo único que hice diferente fue usar UITableViewScrollPositionNone en lugar de ScrollPositionTop para que los usuarios pudieran ver la mayor cantidad posible de la tabla sobre la fila seleccionada. – RanLearns

+1

Esto no funciona para mí porque en las versiones más nuevas de iOS (5 y 6) no veo que el OS configure marcos hasta que aparezca viewWillAppear. viewWillLayoutSubviews/viewDidLayoutSubviews no se llaman hasta después de viewDidAppear. – Logachu

2

Si lo pongo en viewDidLoad o viewWillAppear continuación, se bloquea con un NSRangeException, presumiblemente porque la mesa no está configurado todavía.

¿Por qué la mesa no está configurada todavía? ¿En qué método lo estás configurando?

+0

bien se crea en cellforrowatindexpath – cannyboy

+1

Puede cargar la tabla en viewWillAppear –

1

Acabo de terminar de luchar con esto. El mío fue agregar una barra de búsqueda a la parte superior de la lista, inicialmente metida en la parte superior ... ala algunas de las aplicaciones principales. De hecho, ¡iba a hacer la misma pregunta!

Me temo que puedo ofrecer esto, ya que parece que los que ofrecen cosas son golpeados ... pero ... me sorprendió que no había una solución fácil ... así que terminé haciendo esto:

Utilizo ABTableViewCell (puede buscarlo en google) para las celdas personalizadas dibujadas (¡agradable y rápido!), Y cuando me llaman para DIBUJAR la segunda fila (puede hacerlo en las celdas personalizadas sin ABTableViewCell), lo configuro allí , con un solo semáforo fuego:

if (self.mOnlyOnce == NO && theRow > 1) { 
    self.mOnlyOnce = YES; 
    [self.mParentTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
} 

(elija su fila/sección adecuada, ya que se adapte a usted ... si estuvieran en la misma sección, lo que probablemente estar fijándose una fila a otra que no sea 0)

Si odias mi solución (ya que no puedo comentar aún), hazme el favor de dejarla en cero & dejando que llegue una mejor solución a la cima.

Ah, también, hay una entrada sobre ocultar su búsqueda en la parte superior ... pero la mía ya estaba hecha como una celda personalizada ... aquí está esa link.

disfrutar

-1

en iOS 8 y por encima de [self.tableView reloadData] en viewWillAppear antes scrollToRowAtIndexPath no funciona, usted tiene que hacer la recarga en viewDidAppear como se indica a continuación:

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

    [self.tableView reloadData]; 

    [self.tableView scrollToRowAtIndexPath:[[NSIndexPath indexPathForRow:18 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

} 

Nota: debe usar UITableViewScrollPositionTop, de lo contrario, el desplazamiento no será el esperado y puede desplazarse hacia la parte inferior e incluso hacia las áreas en blanco después de la última fila si especifica scrollToRow como última fila.

Creo que en iOS 8 y superiores la primera vez que se carga tableView no se cargan todos los datos utilizados para construir la tabla, esa es la razón por la que tiene que usar [tableView reload] que creo que es un poco extraño.

2

Llamar scrollToRowAtIndexPath: en viewWillAppear: no funciona para mí porque tableView no está cargado todavía. Pero podría resolver esto llamando al scrollToRowAtIndexPath: después de un poco de retraso.

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

    [self performSelector:@selector(scrollToCell) withObject:nil afterDelay:0.1]; 
} 

- (void) scrollToCell 
{ 
    [_tableView reloadData]; 
    NSIndexPath *scrollToPath = [NSIndexPath indexPathForRow:5 inSection:0]; 
    [_tableView scrollToRowAtIndexPath:scrollToPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
} 

Espero que ayude a alguien.

+2

Esta respuesta funciona mejor, pero en su lugar puede usar dispatch_after también. – harshalb

+0

Probé muchas cosas en iOS 8 y solo esto funciona. Pero también funciona con un 'dispatch_async' en el hilo principal. –

+0

retraso de 0 también funciona bien, y se ve mejor que 100ms donde todavía lo verá saltar 100ms después de empujar la mesa –

1

Puede usar GCD para enviar el desplazamiento a la siguiente iteración del ciclo de ejecución principal en viewDidLoad para lograr este comportamiento. El desplazamiento se realizará antes de que se muestre la vista de tabla en la pantalla, por lo que no habrá parpadeo.

- (void)viewDidLoad { 
    dispatch_async (dispatch_get_main_queue(), ^{ 
     NSIndexPath *indexPath = YOUR_DESIRED_INDEXPATH; 
     [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
    }]; 
} 
4

que tuve el mismo problema, después de intentar todo, esto funcionó, la clave es si usted está utilizando el diseño automático, debe escribir código en scrollToBottom viewDidLayoutSubviews

inicializar scrollToBottom true y luego hacer esto

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 
    // Scroll table view to the last row 
    [self scrollToBottom]; 
} 

-(void)scrollToBottom { 
    if (shouldScrollToLastRow) 
    { 
     CGPoint bottomOffset = CGPointMake(0, self.tableView.contentSize.height - self.tableView.bounds.size.height); 
     [self.tableView setContentOffset:bottomOffset animated:NO]; 
    } } 

esta manera se asegurará de que está casi en la parte inferior de estás tableView pero podría no ser en la parte inferior como su imposible saber el fondo de compensación exacta cuando estás en la parte superior de la tableView , entonces después de eso podemos implementar scro llViewDidScroll

-(void)scrollViewDidScroll: (UIScrollView*)scrollView 
{ 
    float scrollViewHeight = scrollView.frame.size.height; 
    float scrollContentSizeHeight = scrollView.contentSize.height; 
    float scrollOffset = scrollView.contentOffset.y; 

    // if you're not at bottom then scroll to bottom 
    if (!(scrollOffset + scrollViewHeight == scrollContentSizeHeight)) 
    { 
     [self scrollToBottom]; 
    } else { 
    // bottom reached now stop scrolling 
     shouldScrollToLastRow = false; 
    } 
} 
Cuestiones relacionadas