411

在我的表格视图中,我必须滚动到顶部。但我不能保证第一个对象将是第 0 行第 0 行。可能是我的表格视图将从第 5 部分开始。

所以我得到一个例外,当我打电话时:

[mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];

还有另一种方法可以滚动到表格视图的顶部吗?

4

36 回答 36

895

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)
于 2009-04-07T10:23:31.307 回答
247

注意:此答案对 iOS 11 及更高版本无效。

我更喜欢

[mainTableView setContentOffset:CGPointZero animated:YES];

如果您的表格视图上有一个顶部插图,则必须减去它:

[mainTableView setContentOffset:CGPointMake(0.0f, -mainTableView.contentInset.top) animated:YES];
于 2012-01-17T15:24:49.243 回答
87

可能的行动:

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)
  }
于 2016-02-16T09:37:32.817 回答
27

最好不要使用 NSIndexPath (空表),也不要假设顶点是 CGPointZero (内容插入),这就是我使用的 -

[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];

希望这可以帮助。

于 2014-08-13T19:53:56.950 回答
22

斯威夫特 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)
于 2017-10-08T12:54:00.137 回答
21

在 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)
}
于 2018-01-18T07:14:38.097 回答
19

我遇到了一个问题,调用在空的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
于 2017-09-26T23:50:28.857 回答
18

不要使用

 tableView.setContentOffset(.zero, animated: true)

它有时会不正确地设置偏移量。例如,在我的例子中,单元格实际上略高于带有安全区域插图的视图。不好。

代替使用

 tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
于 2018-11-11T03:49:33.507 回答
12

对于具有 的表,contentInset将内容偏移设置为CGPointZero不起作用。它会滚动到内容顶部与滚动到桌面。

考虑到内容插入会产生这样的结果:

[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:NO];
于 2015-06-17T10:33:27.240 回答
10

此代码可让您将特定部分滚动到顶部

CGRect cellRect = [tableinstance rectForSection:section];
CGPoint origin = [tableinstacne convertPoint:cellRect.origin 
                                    fromView:<tableistance>];
[tableinstance setContentOffset:CGPointMake(0, origin.y)];
于 2013-04-26T10:17:05.360 回答
9

斯威夫特 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)
}

这似乎是多余的,因为您已经在主队列中,但这并不是因为它序列化了动画。

于 2019-11-29T21:36:01.990 回答
8

迅速:

tableView.setContentOffset(CGPointZero, animated: true)
于 2014-12-07T15:04:58.127 回答
8

斯威夫特 3

tableView.setContentOffset(CGPoint.zero, animated: true)

如果tableView.setContentOffset不工作。

采用:

tableView.beginUpdates()
tableView.setContentOffset(CGPoint.zero, animated: true)
tableView.endUpdates()
于 2018-01-11T08:23:04.490 回答
7

添加到已经说过的内容,您可以创建一个扩展 (Swift) 或类别 (Objective C),以便将来更容易做到这一点:

迅速:

extension UITableView {
    func scrollToTop(animated: Bool) {
        setContentOffset(CGPointZero, animated: animated)
    }
}

任何时候您想将任何给定的 tableView 滚动到顶部,您都可以调用以下代码:

tableView.scrollToTop(animated: true)
于 2015-09-07T17:21:39.280 回答
7

由于我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)
}
于 2017-02-01T08:37:27.263 回答
6

我更喜欢以下内容,因为它考虑了插图。如果没有 inset,它仍然会滚动到顶部,因为 inset 将为 0。

tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
于 2017-05-04T19:01:36.720 回答
5

斯威夫特:

如果您没有 tableView 标头:

tableView.setContentOffset(CGPointMake(0,  UIApplication.sharedApplication().statusBarFrame.height ), animated: true)

如果是这样的话 :

tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height   + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
于 2015-02-04T08:23:18.280 回答
4

这是我用来在 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)
    }
}
于 2017-09-22T20:32:21.103 回答
4

在 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()
于 2019-04-30T08:32:57.837 回答
3

使用 contentOffset 不是正确的方法。这会更好,因为它是表格视图的自然方式

tableView.scrollToRow(at: NSIndexPath.init(row: 0, section: 0) as IndexPath, at: .top, animated: true)
于 2017-06-12T04:41:46.757 回答
3

这是唯一对我有用的代码片段

斯威夫特 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 是我的标题和表格视图单元格的高度

于 2018-07-10T05:14:54.567 回答
2
func scrollToTop() {
        NSIndexPath *topItem = [NSIndexPath indexPathForItem:0 inSection:0];
        [tableView scrollToRowAtIndexPath:topItem atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

在任何你想要 UITableView 滚动到顶部的地方调用这个函数

于 2017-01-04T06:24:37.923 回答
2

Swift 4通过扩展,处理空表视图:

extension UITableView {
    func scrollToTop(animated: Bool) {
        self.setContentOffset(CGPoint.zero, animated: animated);
    }
}
于 2018-02-20T06:23:32.487 回答
2

我使用 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
            }
        }

    }

}
于 2018-06-07T10:22:59.260 回答
1

迅速

你的行 = selectioncellRowNumber 你的部分如果你有 = selectionNumber 如果你没有设置为零

//UITableViewScrollPosition.Middle or Bottom or Top

var lastIndex = NSIndexPath(forRow:  selectioncellRowNumber, inSection: selectionNumber)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)
于 2015-08-31T10:37:24.527 回答
1

我必须将乘以添加-1 *到状态栏和导航栏的总和,因为它离屏幕的高度,

self.tableView.setContentOffset(CGPointMake(0 , -1 * 
  (self.navigationController!.navigationBar.height +  
  UIApplication.sharedApplication().statusBarFrame.height) ), animated:true)
于 2015-11-12T23:37:20.207 回答
1

这是以编程方式将 ScrollTableView 置顶的代码

迅速:

self.TableView.setContentOffset(CGPointMake(0, 1), animated:true)
于 2017-01-04T06:29:00.843 回答
1

在 Swift-3 中:

self.tableView.setContentOffset(CGPoint.zero, animated: true)
于 2017-01-24T07:41:50.427 回答
0

如果您想在表格中移动滚动动画,请使用此代码。滚动在 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];
于 2014-11-12T03:58:29.420 回答
0

使用斯威夫特:

self.scripSearchView.quickListTbl?.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
于 2017-04-14T06:36:04.023 回答
0

要在完成后完成,请添加此扩展

// MARK: - UIScrollView

extension UIScrollView {

    /// Animate scroll to top with completion
    ///
    /// - Parameters:
    ///   - duration:   TimeInterval
    ///   - completion: Completion block
    func animateScrollToTop(withDuration duration:  TimeInterval,
                            completion:             @escaping (()->())) {

        UIView.animate(withDuration: duration, animations: { [weak self] in
                self?.setContentOffset(CGPoint.zero, animated: false)
            }, completion: { finish in
                guard finish else {
                    return
                }
                completion()
        })
    }
}

tableView.animateScrollToTop(withDuration: 0.25) { 
    // Finish
}
于 2017-06-07T15:45:39.907 回答
0

这是一个 UIScrollView 扩展的简单示例,您可以在应用程序的任何地方使用它。

1)首先,您应该创建enum可能的滚动方向:

enum ScrollDirection {
    case top, right, bottom, left

    func contentOffsetWith(_ scrollView: UIScrollView) -> CGPoint {
        var contentOffset = CGPoint.zero
        switch self {
            case .top:
                contentOffset = CGPoint(x: 0, y: -scrollView.contentInset.top)
            case .right:
                contentOffset = CGPoint(x: scrollView.contentSize.width - scrollView.bounds.size.width, y: 0)
            case .bottom:
                contentOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
            case .left:
                contentOffset = CGPoint(x: -scrollView.contentInset.left, y: 0)
            }
        return contentOffset
    }
}

2)然后添加扩展UIScrollView:

extension UIScrollView {
    func scrollTo(direction: ScrollDirection, animated: Bool = true) {
        self.setContentOffset(direction.contentOffsetWith(self), animated: animated)
    }
}

3)就是这样!现在你可以使用它了:

myScrollView.scrollTo(.top, animated: false)

此滚动绑定到 tableView 的内容大小,它看起来比滚动到更自然CGPoint.zero

于 2020-06-11T06:01:27.047 回答
0

如果你需要使用 Objective-C 或者你仍然爱着:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
于 2021-02-23T08:55:06.670 回答
0

使用 scrollToRow 的解决方案解决了空 TableView 的问题(需要搜索)。

import UIKit

extension UITableView {
    
    public func scrollToTop(animated: Bool = false) {
        if numberOfRows(inSection: 0) > 0 {
            scrollToRow(
                at: .init(row: 0, section: 0),
                at: .top,
                animated: animated
            )
        }
    }
    
}
于 2022-01-09T07:38:42.487 回答
-3

使用此代码UITableview快速实现:

var cell = tableView.dequeueReusableCellWithIdentifier(“cell”)
if cell == nil {
    cell = UITableViewCell(style: .Value1, reuseIdentifier: “cell”)
}
于 2017-02-21T06:41:16.173 回答
-30

如果您不想滚动,您可以在启动时立即启动和停止滚动动画。

    $('document').ready(function() {
    $("html, body").animate({ scrollTop: 0 }, 500);
    return true;
    });

此外,要为 'x' 和 'y' 的 put 值设置动画,传入 0,0 将立即将页面滚动到左上角。

window.scrollTo(x, y);
于 2014-11-19T09:09:53.050 回答