Force UITableView à faire défiler vers les sumts des cellules

Existe-t-il un moyen de faire en sorte que UITableViews fasse défiler les cellules vers les cellules? C'est-à-dire que le haut de la vue tabulaire est toujours le sumt d'un UITableViewCell.

J'ai essayé le drapeau de pageation, mais cela semble faire défiler des pages entières. Je veux juste faire défiler les cellules.

Merci

UTTableView est une sous-class de UIScrollView , vous pouvez donc utiliser la méthode scrollViewDidScroll pour réorganiser votre position de défilement TableView après le défilement.

Vous pouvez utiliser tableView.contentOffset pour get où se trouve votre position de défilement actuelle. Et en le divisant en un nombre significatif, vous pouvez get quelle cellule est en haut.

 int cellIndex = tableView.contentOffset / cellHegiht; 

Ou vous pouvez get la cellule actuellement visible au centre (haut, bas) comme ceci:

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

Après avoir calculé quelle cellule doit être cliquée par son bord en haut (ou en bas), vous pouvez corriger la dérive du bord de la cellule en appelant:

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

Vous pouvez utiliser les methods UIScrollViewDelegate pour activer l'accrochage. Vous pouvez l'activer lorsque l'animation de défilement est terminée ou lorsque l'animation continue. Cela va générer une interaction différente de l'user et ne peut pas dire que l'un est meilleur que l'autre.

Mais juste mettre en œuvre la méthode suivante et rien d'autre ne ressemble à être mon préféré:

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

Cette méthode est appelée lorsque l'user TableView pour notifier l'application. targetContentOffset est une variable inout qui vous permet de définir la position de défilement finale pendant que l'animation se poursuit. En utilisant right cellHeight , votre TableView sera toujours TableView aux cellules.

Si vous avez des sections, j'ai trouvé que c'est l'approche la plus 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]; } 

Bien que totalement correct, je n'ai pas trouvé la réponse par @randle très utile. J'ai lu la documentation des développeurs, et j'étais encore plus confus. Cependant, j'ai finalement découvert à quel point la réponse était simple, mais parfois nous avons besoin d'un peu plus d'aide que d'appeler cette méthode. Voir sous le commentaire // faites défiler jusqu'à la ligne! ici:

 - (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; } 

Maintenant, ceci est pour une table statique statique. Je connais le nombre de rangées, je sais dans quelle rangée je vais. Cela pourrait être étendu à un meilleur code, et l'access aux variables par programmation, mais il montre comment ce code fonctionne dans la pratique à un niveau bas.

J'espère que ceci appenda une couche d'utilité à n'importe qui d'autre recherchant le forum.

J'ai fait une rédaction complète de la méthode ici: http://iosanswers.blogspot.com/2012/02/table-view-forms-scroll-to-selected.html

Cette approche gère une vue de table avec des hauteurs de rangées différentes. Il suppose que la vue de table a une seule section.

 - (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]; } 

Le décalage est calculé par cette méthode d'assistance, qui résume les hauteurs de toutes les lignes au-dessus de la ligne cible.

 - (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; } 

Vous devez simplement appeler scrollToRowAtIndexPath:atScrollPosition:animated: et lui passer le bon path d'index pour la cellule que vous voulez.

Cela fonctionne bien si vous avez des sections et des rangées avec des hauteurs statiques.

 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) }