强制UITableView滚动到单元格的顶部

有没有办法让UITableViews滚动单元格? 也就是说,表视图的顶部始终是UITableViewCell的顶部。

我尝试了分页标志,但似乎滚动整个“页面”。 我只想单元格滚动。

谢谢

UTTableViewUIScrollView的子类,因此您可以使用scrollViewDidScroll方法在滚动后重新排列TableView滚动位置。

您可以使用tableView.contentOffset来获取当前滚动位置。 把它分成一个有意义的数字,你可以得到哪个单元格在最上面。

 int cellIndex = tableView.contentOffset / cellHegiht; 

或者你可以像这样在中心(顶部,底部)获得当前可见的单元格:

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

在计算哪个单元格应该由其顶部(或底部)的边缘点击后,可以通过调用以下方法来纠正从单元格边缘的漂移:

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

您可以使用UIScrollViewDelegate方法来激活捕捉。 您可以在滚动animation完成时或animation继续时激活。 这将产生不同的用户交互,不能说一个更好,那么另一个。

但只是实施下面的方法,没有别的看起来会成为我的最爱:

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

当用户触摸TableView来通知应用程序时,这个方法被调用。 targetContentOffset是一个inoutvariables,因此您可以在animation继续时设置最终滚动位置。 使用正确的cellHeight ,你的TableView将总是捕捉到单元格。

如果你有部分,我发现这是最可靠的方法:

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

虽然完全正确,我没有find@randle的答案非常有帮助。 我读了开发者文档,而且我更加困惑。 我怎么终于发现答案是多么简单,但有时我们需要一点,但比“称这种方法”更多的帮助。 看看下面的评论//滚动到行! 这里:

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

现在,这是一个静态单元格tableView。 我知道行数,我知道我要去哪一行。 这可以扩展到更好的代码,并以编程方式访问variables,但它显示了如何在低层次上实践这个代码。

我希望这会给search论坛的任何人增加一层有用的东西。

我做了一个完整的方法写在这里: http : //iosanswers.blogspot.com/2012/02/table-view-forms-scroll-to-selected.html

这种方法处理不同行高的表格视图。 它假设表格视图有一个单独的部分。

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

偏移量是通过这个帮助器方法计算出来的,它将目标行上方所有行的高度相加。

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

您只需要调用scrollToRowAtIndexPath:atScrollPosition:animated:并将它传递给所需单元格的正确索引path。

如果你有静态高度的部分和行,这效果很好。

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