如何在IOS7 UITableView中返回顶部?

44

在IOS6中,我有以下代码来滚动到UITableView的顶部

[tableView setContentOffset:CGPointZero animated:YES];

在iOS7中,这不再起作用。表视图没有完全滚动到顶部(但几乎是)。


1
你是否可能遗漏了新状态栏样式的20像素?我在很多地方都遇到过这个问题 - 在IB中有一个错误修复程序可以对状态栏进行正确的调整。这可能导致底部或顶部缺失20像素。 - gillyD
12个回答

127
在iOS7中,默认情况下,整个屏幕的UITableView和UIScrollView组件会自动调整内容和滚动指示器插图以使一切正常工作。但是,正如您已经注意到的那样,CGPointZero不再代表带您到视觉“顶部”的内容偏移量。请改用以下方法:
self.tableView.contentOffset = CGPointMake(0, 0 - self.tableView.contentInset.top);

在这里,您不必担心是否有节或行。 您也不需要告诉表视图定位到第一行,然后想知道为什么它没有显示您非常高的表头视图等。


7
我喜欢你的方法。如果你使用[UITableView setContentOffset:animated:]会更好,因为这样你就可以动画到那个位置。 - siburb
@siburb同意,在许多情况下,使用该方法来进行动画处理是更好的方式。 - idStar
@siburb 奇怪,使用 self.tableView.contentOffset 可以正常工作,但是使用 [UITableView setContentOffset:animated:] 就不行了?! - mileusna
8
抱歉,回顾我的评论,我表达得不够清楚。“setContentOffset”是一个实例方法,而不是一个类方法,所以你需要像这样使用它: [self.tableView setContentOffset:CGPointMake(0, 0 - self.tableView.contentInset.top) animated:YES]; - siburb
这个地方非常适合C99语法:(CGPoint){.y = -self.tableView.contentInset.top}。(x 将被初始化为 0。) - Steven Fisher
显示剩余2条评论

23

试试这个:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

3
иҜ·дҪҝз”ЁдёҖдёӘifжқЎд»¶жқҘжЈҖжҹҘиЎЁж јжҳҜеҗҰжңүд»»дҪ•иЎҢгҖӮ - Harikrishnan
最好使用idStar的答案中提供的正确代码来完成。请注意,如果现在没有行,它以后可能会有行,那么它将处于错误的位置(特别是如果您试图使其“正确启动”)。 - Fattie

21
根据@Markus Johansson的答案,这是Swift代码版本:
func scrollToTop() {
    if (self.tableView.numberOfSections > 0 ) {
        let top = NSIndexPath(row: Foundation.NSNotFound, section: 0)
        self.tableView.scrollToRow(at: top as IndexPath, at: .top, animated: true);
    }
}

1
这是对我有效的答案,但是(self.numberOfSectionsInTableView(self.tableView)出现了错误消息,我用tableView.numberOfRowsInSection(0)替换了它,然后它就起作用了。 - Dave G

17

在这里得到一些其他答案的帮助,我设法让它工作起来。为了避免崩溃,首先必须检查是否有某些部分。如果第一个部分没有行,则可以将NsNotFound用作行索引。希望这应该是一个通用函数,放置在UITableViewController中:

-(void) scrollToTop
{
    if ([self numberOfSectionsInTableView:self.tableView] > 0)
    {
        NSIndexPath* top = [NSIndexPath indexPathForRow:NSNotFound inSection:0];
        [self.tableView scrollToRowAtIndexPath:top atScrollPosition:UITableViewScrollPositionTop animated:YES];
    }
}

8
这与我发布的答案几乎相同。因此,您应该接受那个答案。无论如何,如果您的问题已经解决,请接受一个答案,以便它对其他人有帮助。 - Harikrishnan
虽然您可以使用此方法来定位第一行,但不一定会显示在第一行上方的任何表头视图。从语义上讲,您只需要在考虑到所给定的contentInset的情况下设置table view的contentOffset(请参见下面我的答案中的代码)。 - idStar
事实上,情况再简单不过了。使用idStar的代码,这是正确的清空表的代码! - Fattie

4
var indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.sampleTableView.scrollToRowAtIndexPath(indexPath,
atScrollPosition: UITableViewScrollPosition.Top, animated: true)

或者
self.sampleTableView.setContentOffset(CGPoint.zero, animated:false)

3

Swift 3

如果您有表格视图标题,CGPointZero可能无法正常工作,但这种方法始终可以滚动到顶部。

self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.top, animated: false)

3

这是idStar在更新的Swift 3语法中的答案

self.tableView.contentOffset = CGPoint(x: 0, y: 0 - self.tableView.contentInset.top)

带有动画效果:

self.tableView.setContentOffset(CGPoint(x: 0, y: 0 - self.tableView.contentInset.top), animated: true)

3
float systemVersion= [[[UIDevice currentDevice] systemVersion] floatValue];

if(systemVersion >= 7.0f)
{
  self.edgesForExtendedLayout=UIRectEdgeNone;   
}

viewDidLoad()方法中尝试使用以下代码。

2

我知道这个问题已经有答案了,但我想提供另一个选项:

CGRect frame = {{0, 0},{1, 1}};
[self.tableView scrollRectToVisible:frame animated:YES];

这将始终保证UITableView滚动到顶部。 接受的答案:

NSIndexPath* top = [NSIndexPath indexPathForRow:NSNotFound inSection:0];
[self.tableView scrollToRowAtIndexPath:top atScrollPosition:UITableViewScrollPositionTop animated:YES];

因为我滚动到的是tableHeaderView而不是cell,所以这个方法对我无效。

在iOS 6和7上可以使用scrollRectToVisible


2

您仍可以使用scrollToRowAtIndexPath:来实现此目的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接