2011-10-17 8 views

Respuesta

20

UTTableView es una subclase de UIScrollView, por lo que se pueden utilizar scrollViewDidScroll método para reorganizar su posición de desplazamiento TableView después del desplazamiento.

Puede usar tableView.contentOffset para obtener su posición de desplazamiento actual. Y al dividirlo en un número significativo puede obtener qué celda está en la parte superior.

int cellIndex = tableView.contentOffset/cellHegiht; 

O puede obtener celda actualmente visible en el centro (arriba, abajo) así:

NSArray *indexPathsForVisibleRows = [tableView indexPathsForVisibleRows]; 
NSIndexPath *selectedIndexPath = [indexPathsForVisibleRows objectAtIndex:(indexPathsForVisibleRows.count/2)]; //this gets center cell 

Después de calcular qué celda se debe pulsar por su borde en la parte superior (o inferior) se puede corregir la deriva desde el borde celular llamando al:

[tableView scrollToRowAtIndexPath:selectedIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

Usted puede utilizar UIScrollViewDelegate métodos para activar chasquido. Puede activar cuando la animación de desplazamiento se completa o mientras la animación continúa. Esto generará una interacción diferente del usuario y no puede decir que una sea mejor que otra.

Pero sólo la implementación siguiente método y nada más parece que va a ser mi favorito:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset { 
    int cellHeight = 41; 
    *targetContentOffset = CGPointMake(targetContentOffset->x, 
             targetContentOffset->y - (((int)targetContentOffset->y) % cellHeight)); 
} 

Este método se llama cuando el usuario toca arriba en TableView para notificar a la aplicación. targetContentOffset es una variable inout por lo que realmente puede establecer la posición de desplazamiento final mientras la animación continúa. Si utiliza cellHeight, su TableView siempre se ajustará a las celdas.

+2

Gracias por mostrar cómo usar la variable 'inout'. Muy buena característica! – Besi

+0

+1 También le agradezco que indique la variable "inout". – jpswain

+0

Con tus cálculos matemáticos, nunca puedes desplazarte a la última fila de la tabla ... no hay problema para remediarlo. Definitivamente la mejor solución para esto. – scottbates22

0

Simplemente necesita llamar al scrollToRowAtIndexPath:atScrollPosition:animated: y pasarle la ruta de índice correcta para la celda que desea.

1

Aunque totalmente correcto, no encontré la respuesta por @randle muy útil. Leí la documentación de los desarrolladores, y estaba aún más confundido. Sin embargo, finalmente descubrí cuán simple era la respuesta, pero a veces necesitamos un poco más de ayuda que "llamar a este método". Mira debajo del comentario // ¡desplázate a la fila! aquí:

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    if (textField == self.firstInput) { 
     [self.secondInput becomeFirstResponder]; 

     // scroll to row! 
     [self.tableView scrollToRowAtIndexPath: // use the method 
      [NSIndexPath indexPathForRow:1  // get 2nd row (nth row...) 
           inSection:0] // in 1st section (...) 
         // set position: you can use bottom, middle or top. 
         atScrollPosition:UITableViewScrollPositionBottom 
           animated:YES]; // YES or NO. 

    } else if (textField == self.secondInput) { 
     [textField resignFirstResponder]; 
    } 
    return YES; 
} 

Ahora, esto es para una celda estática tableView. Sé la cantidad de filas, sé a qué fila voy. Esto podría ampliarse para mejorar el código y acceder a las variables de forma programática, pero muestra CÓMO funciona este código en la práctica en un nivel bajo.

Espero que esto agregue una capa de utilidad a cualquier persona que busque en el foro.

hice una escritura completa del método aquí: http://iosanswers.blogspot.com/2012/02/table-view-forms-scroll-to-selected.html

3

Si tiene secciones, he encontrado este el método más fiable:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate(BOOL)decelerate { 
    if (decelerate == NO) { 
     [self autoAdjustScrollToTop]; 
    } 
} 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    [self autoAdjustScrollToTop]; 
} 
- (void)autoAdjustScrollToTop { 
    // compare the top two visible rows to the current content offset 
    // and auto scroll so that the best row is snapped to top 
    NSArray *visibleRows = [self.tableView indexPathsForVisibleRows]; 
    NSIndexPath *firstPath = visibleRows[0]; 
    NSIndexPath *secondPath = visibleRows[1]; 
    CGRect firstRowRect = [self.tableView rectForRowAtIndexPath:firstPath]; 
    [self.tableView scrollToRowAtIndexPath:(firstRowRect.origin.y > self.tableView.contentOffset.y ? firstPath : secondPath) atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 
1

Este enfoque se ocupa de una vista de tabla con diferentes alturas de las filas . Asume que la vista de tabla tiene una sola sección.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset { 

    // Find the row where the animation will currently end. 
    NSInteger targetRow = [[self.tableView indexPathForRowAtPoint:*targetContentOffset] row]; 

    // Tell the animation to end at the top of that row. 
    *targetContentOffset = [self offsetForTopOfRow:targetRow]; 
} 

El desplazamiento se calcula mediante este método de ayuda, que suma las alturas de todas las filas por encima de la fila de destino.

- (CGPoint)offsetForTopOfRow:(NSInteger)row { 

    CGPoint offset = CGPointZero; 

    for (int i = 0; i < row; i++) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; 
     CGFloat height = [self.tableView.delegate tableView:self.tableView heightForRowAtIndexPath:indexPath]; 
     offset.y += height; 
    } 

    return offset; 
} 
0

Esto funciona bien si tiene secciones y filas con alturas estáticas.

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
    // Adjust target offset so that cells are snapped to top 
    let cellHeight: CGFloat = 44 
    let headerHeight: CGFloat = 30 
    let section = (indexPathsForVisibleRows?.first?.section ?? 0) + 1 
    targetContentOffset.memory.y -= (targetContentOffset.memory.y % cellHeight) - (CGFloat(sectionIndex) * headerHeight) 
} 
Cuestiones relacionadas