2010-02-25 17 views
12

Me enfrenta con un problema simple pero tedioso. Lo que trato de hacer es convertir una UITableView en una página como UIScrollView, pero habilitar la búsqueda no me sirve de mucho porque no puedo establecer el tamaño de la página para que la vista de tabla se desplace exactamente de su altura para que se muestren las filas 1 .. .10 o 11 ... 20 y así sucesivamente. Lo que me gustaría en cambio es que ninguna celda permanezca recortada encima o debajo de la vista cuando me desplazo (por lo tanto, paginación) sin tener un tipo de rango fijo de las celdas mostradas.UITableVer tamaño de página cuando la búsqueda está habilitada

Muchas gracias

Respuesta

13

sencilla pero eficaz:

- (void)scrollViewDidEndDecelerating:(UITableView *)tableView { 
      int tomove = ((int)tableView.contentOffset.y%(int)tableView.rowHeight); 
      if(tomove < tableView.rowHeight/2) [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y-tomove) animated:YES]; 
      else [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y+(tableView.rowHeight-tomove)) animated:YES]; 
    } 

    - (void)scrollViewDidEndDragging:(UITableView *)scrollView willDecelerate:(BOOL)decelerate { 
      if(decelerate) return; 

      [self scrollViewDidEndDecelerating:scrollView]; 
    } 
+0

no funciona muy bien para mí. Además, como está utilizando DidEndDecelerating, el código no se llama cuando no hay desaceleración (es decir: si la tabla no está "activada", sino que se libera suavemente) – pixelfreak

+0

Debe agregar el mismo código a - (void) scrollViewDidEndDragging :(UIScrollView *) scrollView desacelerará: (BOOL) decelerate si se desacelerará: (BOOL) decelerate es falso – Julien

+0

@Julien Sí, olvidé pegar el segundo método. ¡Nadie lo notó por más de un año! Thx – maxcanna

16

más simple y más eficiente :)

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

    if(decelerate) return; 

    [self scrollViewDidEndDecelerating:scrollView]; 
} 


- (void)scrollViewDidEndDecelerating:(UITableView *)tableView { 

    [tableView scrollToRowAtIndexPath:[tableView indexPathForRowAtPoint: CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y+tableView.rowHeight/2)] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 
+2

. Esta solución funcionó perfectamente para mí y funcionó para cada desplazamiento. La otra solución era un poco inconsistente con sus resultados ... a veces se ajustaba a la parte superior de la celda, otras veces no lo hacía. – codeqi

+0

@codeqi la razón por la que salta a la cima a veces, es porque probablemente tenga un espacio entre sus elementos en el collectioView. En ese caso, el método indexPathForRowAtPoint devolverá 0,0, que lleva a la parte superior. ;) – Lirik

4

Esto funciona como paginación real:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    int tomove = ((int)targetContentOffset->y % (int)self.tableView.rowHeight); 
    if(tomove < self.tableView.rowHeight/2) 
     targetContentOffset->y -= tomove; 
    else 
     targetContentOffset->y += (self.tableView.rowHeight-tomove); 
} 

y hacer esto en -viewDidLoad:

self.tableView.decelerationRate = UIScrollViewDecelerationRateFast; 
+0

Esto casi funciona a la perfección, pero falla para las celdas de pantalla completa cuando se hace una voltereta muy suave (no es suficiente para mover la página). Al instante mueve la celda hacia atrás, en lugar de animarla sin problemas. –

5

A partir de k06a's answer, he refinado un poco por lo que funciona más como el UITableView paginado real. Las diferencias en el comportamiento son bastante notables con las filas de la tabla de pantalla completa. Incluso una mini-película en cualquier dirección debe desplazar la tabla a la siguiente página: Hago esto comprobando primero la velocidad.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset 
{  
    CGFloat rowHeight = tableView.rowHeight; 
    int verticalOffset = ((int)targetContentOffset->y % (int)rowHeight); 
    if (velocity.y < 0) 
    { 
     targetContentOffset->y -= verticalOffset; 
    } 
    else if (velocity.y > 0) 
    { 
     targetContentOffset->y += (rowHeight - verticalOffset); 
    } 
    // No velocity, snap to closest page 
    else 
    { 
     if (verticalOffset < rowHeight/2) 
     { 
      targetContentOffset->y -= verticalOffset; 
     } 
     else 
     { 
      targetContentOffset->y += (rowHeight - verticalOffset); 
     } 
    }  
} 

Tenga en cuenta que, además, el establecimiento de

self.tableView.decelerationRate = UIScrollViewDecelerationRateFast; 

en viewDidLoad: hace que sea más cercana a la realidad, pero no del todo.

He estado jugando con el establecimiento de velocidades de desaceleración aún más rápidas utilizando el code shown here pero no pude hacerlo bien.

3

Y en Swift ...

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { 
    if !decelerate { 
     self.scrollViewDidEndDecelerating(scrollView) 
    } 
} 

func scrollViewDidEndDecelerating(scrollView: UIScrollView) { 
    if let indexPathToScrollTo: NSIndexPath = self.tableView.indexPathForRowAtPoint(CGPointMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y+tableView.rowHeight/2)) { 
     self.tableView.scrollToRowAtIndexPath(indexPathToScrollTo, atScrollPosition: UITableViewScrollPosition.Top, animated: true) 
    } 
} 
Cuestiones relacionadas