UITableView - 滚动到顶部

时间:2009-04-07 09:54:55

标签: ios objective-c

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

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

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

还有其他方法可以滚动到表格视图的顶部吗?

35 个答案:

答案 0 :(得分:804)

UITableView是UIScrollView的子类,因此您也可以使用:

[mainTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];

或者

[mainTableView setContentOffset:CGPointZero animated:YES];

在斯威夫特:

mainTableView.setContentOffset(CGPointZero, animated:true)

在Swift 3&以上:

mainTableView.setContentOffset(.zero, animated: true)

答案 1 :(得分:241)

我更喜欢

[mainTableView setContentOffset:CGPointZero animated:YES];

如果您在表格视图中有一个顶部插图,则必须将其减去:

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

答案 2 :(得分:66)

可能的行动:

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

根据要求修改并使用它。

Swift 4

  func scrollToFirstRow() {
    let indexPath = IndexPath(row: 0, section: 0)
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
  }

答案 3 :(得分:26)

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

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

希望这有帮助。

答案 4 :(得分:19)

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

答案 5 :(得分:12)

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

将内容插入考虑在内会产生这种情况:

[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:NO];

答案 6 :(得分:11)

我在调用空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

答案 7 :(得分:10)

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

CGRect cellRect = [tableinstance rectForSection:section];
CGPoint origin = [tableinstacne convertPoint:cellRect.origin 
                                    fromView:<tableistance>];
[tableinstance setContentOffset:CGPointMake(0, origin.y)];

答案 8 :(得分:9)

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

答案 9 :(得分:8)

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

夫特:

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

只要您想将任何给定的tableView滚动到顶部,您就可以调用以下代码:

tableView.scrollToTop(animated: true)

答案 10 :(得分:8)

夫特:

tableView.setContentOffset(CGPointZero, animated: true)

答案 11 :(得分:7)

Swift 3

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

如果tableView.setContentOffset不起作用。

使用:

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

答案 12 :(得分:6)

斯威夫特:

如果你没有tableView标题:

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

如果是这样的话:

tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height   + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)

答案 13 :(得分:6)

请勿使用

 tableView.setContentOffset(.zero, animated: true)

有时可能会设置不正确的偏移量。例如,以我为例,该单元格实际上位于带有安全区域插图的视图上方。不好。

直接使用

 tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)

答案 14 :(得分:5)

由于我的tableView充满了各种插图,这是唯一运作良好的内容:

Swift 3

if tableView.numberOfSections > 0 && tableView.numberOfRows(inSection: 0) > 0 {
  tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}

Swift 2

if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
  tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}

答案 15 :(得分:5)

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

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

答案 16 :(得分:3)

以下是我在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)
    }
}

答案 17 :(得分:3)

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

tableView.scrollToRow(at: NSIndexPath.init(row: 0, section: 0) as IndexPath, at: .top, animated: true)

答案 18 :(得分:2)

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

extension UITableView {
    func scrollToTop(animated: Bool) {
        self.setContentOffset(CGPoint.zero, animated: animated);
    }
}

答案 19 :(得分:2)

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

迅速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)

P.S。 70是我的标题和表格视图单元格的高度

答案 20 :(得分:1)

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

    }

}

答案 21 :(得分:1)

在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()

答案 22 :(得分:1)

在Swift-3中:

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

答案 23 :(得分:1)

这是代码以ScrollTableView编程顶部

夫特:

self.TableView.setContentOffset(CGPointMake(0, 1), animated:true)

答案 24 :(得分:1)

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL *jsCodeLocation;

#if DEBUG
    NSLog(@"AppDelegate:DEBUG");

#if TARGET_IPHONE_SIMULATOR
    NSLog(@"AppDelegate:DEBUG:TARGET_IPHONE_SIMULATOR");
    jsCodeLocation = [NSURL      URLWithString:@"http://localhost:8081/index.ios.bundle"];
#else
    NSLog(@"AppDelegate:DEBUG:!TARGET_IPHONE_SIMULATOR");
    NSLog(@"To device debug, open RCTWebSocketExecutor.m & replace localhost with MacBook IP.");
    // Get dev host IP Address:
    //    ifconfig | grep inet\ | tail -1 | cut -d " " -f 2
    jsCodeLocation = [NSURL URLWithString:@"http://19.244.52.152:8081/ReactComponent/index.ios.bundle"];
#endif

#else
    NSLog(@"AppDelegate:RELEASE jsbundle");
    jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif

    RCTRootView * rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                     moduleName:@"FPDemo"
                                              initialProperties:nil
                                                  launchOptions:nil];
    self.view = rootView;
}

在任何地方调用此函数UITableView滚动到顶部

答案 25 :(得分:1)

我不得不将-1 *乘以状态栏和导航栏的总和,因为它已从屏幕上移开了这个高度,

self.tableView.setContentOffset(CGPointMake(0 , -1 * 
  (self.navigationController!.navigationBar.height +  
  UIApplication.sharedApplication().statusBarFrame.height) ), animated:true)

答案 26 :(得分:1)

这是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

更自然

答案 27 :(得分:0)

Swift 5,iOS 13

我知道这个问题已经有32个答案,但是根据我的经验,只有一种方法可以在所有情况下使用:

tableView.scrollToRow(at: IndexPath(row: someArray.count - 1, section: 0), at: .bottom, animated: true)

如果您正在使用异步网络调用,带有使用键盘进行动画处理的表格的自定义视图控制器等,则此问题中的热门答案通常会滚动到几乎底部,而不是最后一个单元格的绝对底部。无论每次用户界面多么复杂,此方法都将使您到达表的绝对末端。

答案 28 :(得分:0)

如果你需要使用 Objective-C 或者你仍然喜欢:

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

答案 29 :(得分: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
}

答案 30 :(得分:0)

使用Swift:

self.scripSearchView.quickListTbl?.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)

答案 31 :(得分:0)

in swift

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

// UITableViewScrollPosition.Middle或Bottom或Top

var lastIndex = NSIndexPath(forRow:  selectioncellRowNumber, inSection: selectionNumber)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)

答案 32 :(得分: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];

答案 33 :(得分:-3)

在swift中使用此代码实现UITableview

var cell = tableView.dequeueReusableCellWithIdentifier(“cell”)
if cell == nil {
    cell = UITableViewCell(style: .Value1, reuseIdentifier: “cell”)
}

答案 34 :(得分:-26)

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

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

另外,为&#39; x&#39;设置动画值。并且&#39; y&#39;,传入0,0会立即将页面滚动到左上角。

window.scrollTo(x, y);