在我的表格视图中,我必须滚动到顶部。但我不能保证第一个对象将是第 0 行第 0 行。可能是我的表格视图将从第 5 部分开始。
所以我得到一个例外,当我打电话时:
[mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
还有另一种方法可以滚动到表格视图的顶部吗?
UITableView 是 UIScrollView 的子类,所以你也可以使用:
[mainTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
或者
[mainTableView setContentOffset:CGPointZero animated:YES];
在 Swift 中:
mainTableView.setContentOffset(CGPointZero, animated:true)
在 Swift 3 及更高版本中:
mainTableView.setContentOffset(.zero, animated: true)
注意:此答案对 iOS 11 及更高版本无效。
我更喜欢
[mainTableView setContentOffset:CGPointZero animated:YES];
如果您的表格视图上有一个顶部插图,则必须减去它:
[mainTableView setContentOffset:CGPointMake(0.0f, -mainTableView.contentInset.top) animated:YES];
tableView
顶部有非零 contentInset
时,它不起作用。例如:tableView.contentInset = UIEdgeInsetsMake(5.0f, 0.0f, 250.0f, 0.0f);
。如果是这种情况,在您的代码中,tableView
会滚动到 (0.0f, 5.0f)
。
[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];
-scrollView.adjustedContentInset.top
。
可能的行动:
1
func scrollToFirstRow() {
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}
2
func scrollToLastRow() {
let indexPath = NSIndexPath(forRow: objects.count - 1, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)
}
3
func scrollToSelectedRow() {
let selectedRows = self.tableView.indexPathsForSelectedRows
if let selectedRow = selectedRows?[0] as? NSIndexPath {
self.tableView.scrollToRowAtIndexPath(selectedRow, atScrollPosition: .Middle, animated: true)
}
}
4
func scrollToHeader() {
self.tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
}
5
func scrollToTop(){
self.tableView.setContentOffset(CGPointMake(0, UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
}
禁用滚动到顶部:
func disableScrollsToTopPropertyOnAllSubviewsOf(view: UIView) {
for subview in view.subviews {
if let scrollView = subview as? UIScrollView {
(scrollView as UIScrollView).scrollsToTop = false
}
self.disableScrollsToTopPropertyOnAllSubviewsOf(subview as UIView)
}
}
根据需要修改和使用它。
斯威夫特 4
func scrollToFirstRow() {
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
最好不要使用 NSIndexPath (空表),也不要假设顶点是 CGPointZero (内容插入),这就是我使用的 -
[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];
希望这可以帮助。
斯威夫特 4:
这很好用:
//self.tableView.reloadData() if you want to use this line remember to put it before
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
UITableViewStyleGrouped
(标题随内容滚动),这段代码有效。确保您在主线程中并在视图出现后启动此代码 (viewDidAppear
)。如果您仍然有问题,请尝试将代码放入:DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: { // the code }
在 iOS 11 上,无论通话中状态栏是否可见,都可以使用 adjustedContentInset
正确滚动到顶部。
if (@available(iOS 11.0, *)) {
[tableView setContentOffset:CGPointMake(0, -tableView.adjustedContentInset.top) animated:YES];
} else {
[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:YES];
}
迅速:
if #available(iOS 11.0, *) {
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.adjustedContentInset.top), animated: true)
} else {
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
}
不要使用
tableView.setContentOffset(.zero, animated: true)
它有时会不正确地设置偏移量。例如,在我的例子中,单元格实际上略高于带有安全区域插图的视图。不好。
代替使用
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
我遇到了调用在空 tableView
上尝试某些方法的问题。这是 Swift 4 处理空表视图的另一个选项。
extension UITableView {
func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section)
}
func scrollToTop(animated: Bool) {
let indexPath = IndexPath(row: 0, section: 0)
if self.hasRowAtIndexPath(indexPath: indexPath) {
self.scrollToRow(at: indexPath, at: .top, animated: animated)
}
}
}
用法:
// from yourViewController or yourTableViewController
tableView.scrollToTop(animated: true)//or false
对于具有 contentInset
的表,将内容偏移设置为 CGPointZero
将不起作用。它会滚动到内容顶部与滚动到桌面。
考虑到内容插入会产生这样的结果:
[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:NO];
此代码可让您将特定部分滚动到顶部
CGRect cellRect = [tableinstance rectForSection:section];
CGPoint origin = [tableinstacne convertPoint:cellRect.origin
fromView:<tableistance>];
[tableinstance setContentOffset:CGPointMake(0, origin.y)];
斯威夫特 5,iOS 13
我知道这个问题已经有了很多答案,但根据我的经验,这种方法总是有效的:
let last = IndexPath(row: someArray.count - 1, section: 0)
tableView.scrollToRow(at: last, at: .bottom, animated: true)
如果您正在使用动画(如键盘)或某些异步任务,则尤其如此 - 其他答案通常会滚动到几乎底部。如果由于某种原因这并没有让你一直走到底部,那几乎可以肯定是因为一个竞争动画,所以解决方法是将这个动画分派到主队列的末尾:
DispatchQueue.main.async {
let last = IndexPath(row: self.someArray.count - 1, section: 0)
self.tableView.scrollToRow(at: last, at: .bottom, animated: true)
}
这似乎是多余的,因为您已经在主队列中,但这并不是因为它序列化了动画。
top
而不是 bottom
迅速:
tableView.setContentOffset(CGPointZero, animated: true)
斯威夫特 3
tableView.setContentOffset(CGPoint.zero, animated: true)
如果 tableView.setContentOffset
不起作用。
利用:
tableView.beginUpdates()
tableView.setContentOffset(CGPoint.zero, animated: true)
tableView.endUpdates()
由于我的 tableView
充满了各种插图,因此这是唯一运作良好的东西:
斯威夫特 3
if tableView.numberOfSections > 0 && tableView.numberOfRows(inSection: 0) > 0 {
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
斯威夫特 2
if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}
添加到已经说过的内容,您可以创建一个扩展 (Swift) 或类别 (Objective C),以便将来更容易做到这一点:
迅速:
extension UITableView {
func scrollToTop(animated: Bool) {
setContentOffset(CGPointZero, animated: animated)
}
}
任何时候您想将任何给定的 tableView 滚动到顶部,您都可以调用以下代码:
tableView.scrollToTop(animated: true)
我更喜欢以下内容,因为它考虑了插图。如果没有 inset,它仍然会滚动到顶部,因为 inset 将为 0。
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
斯威夫特:
如果您没有 tableView 标头:
tableView.setContentOffset(CGPointMake(0, UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
如果是这样 :
tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
这是我用来在 iOS 11 上正常工作的方法:
extension UIScrollView {
func scrollToTop(animated: Bool) {
var offset = contentOffset
if #available(iOS 11, *) {
offset.y = -adjustedContentInset.top
} else {
offset.y = -contentInset.top
}
setContentOffset(offset, animated: animated)
}
}
在 Swift 5 中,非常感谢@Adrian 的回答
extension UITableView{
func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
return indexPath.section < numberOfSections && indexPath.row < numberOfRows(inSection: indexPath.section)
}
func scrollToTop(_ animated: Bool = false) {
let indexPath = IndexPath(row: 0, section: 0)
if hasRowAtIndexPath(indexPath: indexPath) {
scrollToRow(at: indexPath, at: .top, animated: animated)
}
}
}
用法:
tableView.scrollToTop()
使用 contentOffset 不是正确的方法。这会更好,因为它是表格视图的自然方式
tableView.scrollToRow(at: NSIndexPath.init(row: 0, section: 0) as IndexPath, at: .top, animated: true)
这是唯一对我有用的代码片段
斯威夫特 4:
tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
tableView.setContentOffset(CGPoint(x: 0, y: -70), animated: true)
PS 70 是我的标题和表格视图单元格的高度
func scrollToTop() {
NSIndexPath *topItem = [NSIndexPath indexPathForItem:0 inSection:0];
[tableView scrollToRowAtIndexPath:topItem atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
在任何你想要 UITableView 滚动到顶部的地方调用这个函数
Swift 4 通过扩展,处理空表视图:
extension UITableView {
func scrollToTop(animated: Bool) {
self.setContentOffset(CGPoint.zero, animated: animated);
}
}
我使用 tabBarController 并且在每个选项卡的 tableview 中都有几个部分,所以这对我来说是最好的解决方案。
extension UITableView {
func scrollToTop(){
for index in 0...numberOfSections - 1 {
if numberOfSections > 0 && numberOfRows(inSection: index) > 0 {
scrollToRow(at: IndexPath(row: 0, section: index), at: .top, animated: true)
break
}
if index == numberOfSections - 1 {
setContentOffset(.zero, animated: true)
break
}
}
}
}
我必须将乘以 -1 *
加到状态栏和导航栏的总和上,因为它会离开屏幕的那个高度,
self.tableView.setContentOffset(CGPointMake(0 , -1 *
(self.navigationController!.navigationBar.height +
UIApplication.sharedApplication().statusBarFrame.height) ), animated:true)
迅速
你的行 = selectioncellRowNumber 你的部分如果你有 = selectionNumber 如果你没有设置为零
//UITableViewScrollPosition.Middle or Bottom or Top
var lastIndex = NSIndexPath(forRow: selectioncellRowNumber, inSection: selectionNumber)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)
这是以编程方式将 ScrollTableView 置顶的代码
迅速:
self.TableView.setContentOffset(CGPointMake(0, 1), animated:true)
在 Swift-3 中:
self.tableView.setContentOffset(CGPoint.zero, animated: true)
我发现在 iPhone、iPad 和 macCatalyst (macOS) 下强制 UITableViewController
滚动到顶部的最简单方法如下:
准备从 [tableView:numberOfRowsInSection:] 返回 0
调用 [self.tableView reloadData]
调用 [self.tableView layoutIfNeeded]
准备从 [tableView:numberOfRowsInSection:] 返回实际行数
调用 [self.tableView reloadData]
如果您想在表格中移动滚动动画,请使用此代码。滚动在 0.5 秒内以动画移动到顶部。
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[_tableContent scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
[UIView commitAnimations];
self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.top, animated: true)
似乎适用于 iOS 11