UICollectionView + AFNetworking + AutoScroll / Pagination?

Utilizo UICollectionView + AFNetworking 2 para cargar imágenes de forma asíncrona desde un service web. Está funcionando muy bien Sin embargo, ¿cómo implemento el desplazamiento automático (cuando el usuario llega al final de la página, o cerca de ella, se llama a la API para search más celdas).

He visto muchos ejemplos pero no parece ser una buena práctica. Por ejemplo, un tutorial sugirió scrollViewDidScroll , pero se llama cada vez que se desplaza la vista. ¿Es esa la implementación correcta?

PD. Estoy codificando en Swift.

Aquí está mi código de creación de celda:

 func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell! { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath) as UICollectionViewCell let offer = self.offers[indexPath.row] var cellImageView = cell.viewWithTag(100) as UIImageView let requestURL = NSURLRequest(URL: offer.largeImageURL) cellImageView.setImageWithURLRequest( requestURL, placeholderImage:placeholderImage, success: { (request:NSURLRequest!, response:NSHTTPURLResponse!, image:UIImage!) in cellImageView.image = image }, failure: { (request:NSURLRequest!, response:NSHTTPURLResponse!, error:NSError!) in NSLog("GET Image Error: " + error.localizedDescription) } ) return cell } 

Podría hacerlo en un método de delegado scrollViewDidScroll o collectionView:cellForItemAtIndexPath: (aquí puede detectar que la última celda se está cargando). Lo que debería hacer es crear un contenedor para la llamada AFNetworking para evitar que cargue los datos varias veces (algún tipo de indicador que indique que ya se está cargando).

Después de eso, podría insert una celda adicional con algún tipo de indicador de actividad en la parte inferior y eliminarla después de que AFNetworking llamada de AFNetworking .

Debería usar el método willEndDragging UIScrollview delegate para determinar dónde la scrollview dejará de desplazarse. - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset

Esto tiene varias ventajas sobre los otros methods:

  1. didScroll se llamará cada vez que se desplace la scrollview, incluso en fracciones, e incluso cuando se active desde el código. He visto a didScroll llamarse incluso con un cambio de límites, como cuando cambia la orientación, especialmente en iPad. ¡Lo llaman con demasiada frecuencia!
  2. didEndDecelerating puede no recibir llamadas si la scrollview se detiene de repente, como cuando el usuario presiona y mantiene presionada la scrollview mientras se está desacelerando
  3. willEndDragging solo se llamará cuando el usuario desplace su vista de desplazamiento, no por cambios de código / layout.

En willEndDragging, use el desplazamiento de contenido objective para determinar si necesita cargar más resultados. Una vez que su API haya terminado de search datos, simplemente llame a reloadData en la vista de la colección y se mostrarán los resultados nuevos. Tenga en count que el objective contentOffset es un puntero, por lo que tendrá que usar targetContentOffset->y para get el objective y position.

El código real para hacerlo será dependiente de la implementación, por lo que no voy a include ninguna muestra, pero debería ser lo suficientemente simple como para codificar.

Sí, usa scrollViewDidScroll para verificar que estás en la parte inferior, que hacer cualquier trabajo que necesites (colocar loader, cargar datos, etc.).

Puede usar el componente listo SVInfiniteScrolling (que es parte de SVPullToRefresh ). O mira su implementación para inspirarte.

¡Feliz encoding!

Estoy usando este código en mi proyecto. Lo escribí con Obj-C y no sé lo suficiente para convertirlo en Swift. Entonces, si puede convertir, puede detectarse si el usuario llega al final de la página de esa forma;

 - (BOOL)detectEndofScroll { BOOL scrollResult = NO; CGPoint offset = _collectionView.contentOffset; CGRect bounds = _collectionView.bounds; CGSize size = _collectionView.contentSize; UIEdgeInsets inset = _collectionView.contentInset; float yAxis = offset.y + bounds.size.height - inset.bottom; float h = size.height; if(yAxis+14 > h) { scrollResult = YES; } else { scrollResult = NO; } return scrollResult; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { if ([self detectEndofScroll]) { // load more data } }