2011-05-16 16 views
30

¿Hay alguna manera de desencadenar un evento, como con un IBAction, cuando un usuario se desplaza al final de un UITableView? Me gustaría agregar más filas si esto sucede. ¿Cómo hago esto?Agregar filas a UITableView cuando se desplaza hacia abajo

+0

posible duplicado de [\ [iPhone \] Cómo saber cuándo UITableView se desplazó hacia abajo] (http://stackoverflow.com/questions/5137943/iphone-how-to-know-when-uitableview-did -scroll-to-bottom) –

+0

Por favor, busque antes de publicar. Al buscar en su título, aparece esta pregunta que he vinculado, que tiene la misma información que la respuesta que Henri le ha dado. –

+2

Aquí hay una demostración de infinita UITableView, usando Swift: https://github.com/i-schuetz/tableview_infinite carga datos usando una tarea asíncrona y muestra un pie de página de carga. – Ixx

Respuesta

38

Simplemente escuche el método de delegado scrollViewDidScroll:, compare el desplazamiento de contenido con el posible desplazamiento actual y si es inferior a un umbral, llame a su método para actualizar la tabla. No olvide llamar al [tableView reloadData] para asegurarse de que vuelva a cargar los datos recién agregados.

EDITAR: Unir el código abstracto, no estoy seguro si funciona, pero debería.

- (void)scrollViewDidScroll: (UIScrollView *)scroll { 
    // UITableView only moves in one direction, y axis 
    CGFloat currentOffset = scroll.contentOffset.y; 
    CGFloat maximumOffset = scroll.contentSize.height - scroll.frame.size.height; 

    // Change 10.0 to adjust the distance from bottom 
    if (maximumOffset - currentOffset <= 10.0) { 
      [self methodThatAddsDataAndReloadsTableView]; 
    } 
} 
+0

mente mostrando algunas ¿código? – aherlambang

+0

No tiene una atmósfera de proyecto para mostrar rápidamente algo. Supongo que su viewController es el delegado de tableView. Si es así, simplemente agregue scrollViewDidScroll: al viewController y utilícelo como el lugar para activar el método de actualización. Comparar el contentOffset.y con el máximo (contenSize.y - tableView.frame.size.height) debería ser bastante sencillo. –

+0

La clave es darse cuenta de que UITableView es una subclase de UIScrollView y también transmite los métodos de delegado. –

0

No estoy seguro de por qué querría hacer esto, pero me imagino que podría agregar algún código a su método cellForRowAtIndexPath para que si indexPath.row == la última fila, llame al método para agregar más filas. ..

+4

porque me gustaría llamar a un servicio web REST para agregar más filas ya que hay más entradas que puede ver el usuario, en lugar de tener un tipo de "cargar más publicaciones", ¿por qué no hacerlo automáticamente? – aherlambang

57

A menos Es un poco tarde, pero creo que he encontrado una solución mejor:

en lugar de

- (void)scrollViewDidScroll: (UIScrollView)scroll 

i utilizado

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 

Esto es mucho más conveniente , porque el evento solo se desencadena una vez. Utilicé este código en mi aplicación para cargar más filas en mi vista de tabla en la parte inferior (tal vez reconozcas este tipo de recarga desde la aplicación de Facebook, solo la diferencia que están actualizando en la parte superior).

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {  
    NSInteger currentOffset = scrollView.contentOffset.y; 
    NSInteger maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height; 

    if (maximumOffset - currentOffset <= -40) { 
     NSLog(@"reload"); 
    } 
} 

Espero que alguien ayude esto.

+0

Esto es lo que necesitaba para hacer una sola llamada a mi servidor. '- (void) scrollViewDidScroll:' se activa muchas veces para hacer una llamada a su servidor. A menos que haga lo que @Henri Normak sugirió anteriormente en sus comentarios y agregue un cheque para la actualización. Esto es mucho más simple. Gracias @ user944351 – Ben

+0

buena solución. +1 Gracias –

+0

Esta es la mejor solución. código de limpieza, no ivar – OMGPOP

1
NSInteger currentOffset = scrollView.contentOffset.y; 
NSInteger maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height; 

// Hit Bottom? 
if ((currentOffset > 0) && (maximumOffset - currentOffset) <= 10) { 
    // Hit Bottom !! 
} 
1

Se puede lograrse de manera mucho más simple que supongo, sólo tiene que determinar la dirección de desplazamiento como en este caso es cuando el usuario se desplaza hacia abajo.

Primero en su archivo .h declara una variable:

CGPoint pointNow; 

En el archivo .m, en el método scrollViewDidScroll necesitamos implementar este código: -

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 
    if (scrollView.contentOffset.y > pointNow.y) { 
     //Enter code here 
    } 
} 
14

utilizo este fragmento. en tableView:willDisplayCell:forRowAtIndexPath: lo compruebo, si la celda con la última ruta de índice está a punto de aparecer.

Para una tableView con una sección:

[indexPath isEqual:[NSIndexPath indexPathForRow:[self tableView:self.tableView numberOfRowsInSection:0]-1 inSection:0] 

con más secciones:

[indexPath isEqual:[NSIndexPath indexPathForRow:[self tableView:self.tableView numberOfRowsInSection:0]-1 inSection:[self numberOfSectionsInTableView:self.tableView]-1] 

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if(!_noMoreDataAvailable) 
    { 
     if ([indexPath isEqual:[NSIndexPath indexPathForRow:[self tableView:self.tableView numberOfRowsInSection:0]-1 inSection:0]]) 
     { 
      [self.dataSourceController fetchNewData]; 
     } 
    } 
} 

después de ir a buscar la dataSourceController informará al delegado tableView y esto se volverá a cargar los datos .

+2

respuesta brillante, gusta mucho más esta opción scrollViewDidScroll compara - vikingosegundo gracias! – Rob

+0

Si usa celdas de carga o de error, asegúrese de tener una verificación pequeña como: if (indexPath.row> 5) o simplemente configure boolean noMoreDataAvailble en false. –

+0

No es genial si quiere cargar los datos un poco antes de que el usuario llegue a la última celda. Creo que 'fluye' mejor cuando lo cargas unas pocas celdas antes de – Tander

1

Swift

Aquí está la versión de Swift @user944351's answer:

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { 

    let currentOffset = scrollView.contentOffset.y 
    let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height 

    if maximumOffset - currentOffset <= -40 { 
     print("reload") 
    } 
} 

Sólo añadir este método a la clase UITableView delegado. Encontré -40 demasiado grande pero puede ajustarlo según sus necesidades.

Más información

  • Ver my fuller answer que tiene un ejemplo de método para recargar los datos utilizando límites y las correcciones para la base de datos.
Cuestiones relacionadas