Uitableview-scroll to the top

In my table view I have to scroll to the top. But I cannot guarantee that the first object is going to be section 0, row 0. May be that my table view will start from section number 5.

So I get an exception, when I call:

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

Is there another way to scroll to the top of table view?

转载于:https://stackoverflow.com/questions/724892/uitableview-scroll-to-the-top

30个回答

UITableView is a subclass of UIScrollView, so you can also use:

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

Or

[mainTableView setContentOffset:CGPointZero animated:YES];

And in Swift:

mainTableView.setContentOffset(CGPointZero, animated:true)

And in Swift 3 & above:

mainTableView.setContentOffset(.zero, animated: true)
weixin_41568127
?yb? nope, i tested this too, and all other methods to scroll
大约 2 年之前 回复
weixin_41568110
七度&光 self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.top, animated: true) seems to work in iOS 11
大约 2 年之前 回复
weixin_41568127
?yb? nope, hoping for iOS12
大约 2 年之前 回复
csdnceshi55
~Onlooker did you find a fix for it?
大约 2 年之前 回复
weixin_41568127
?yb? anyone noticed that in iOS11 this all is broken and not scrolling correctly in some cases?
2 年多之前 回复
csdnceshi74
7*4 Thank you, this is helpful.
接近 3 年之前 回复
weixin_41568208
北城已荒凉 This worked fine for me (Swift 3, XCode 8), but only after I remembered to call endRefreshing() before since my UITableView contains an UIRefreshControl.
大约 3 年之前 回复
weixin_41568174
from.. This didn't work for me in a table with multiple sections, each with a header. I had to use tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
大约 3 年之前 回复
csdnceshi57
perhaps? mainTableView.setContentOffset(CGPoint.zero, animated:true) is more "swifty".
4 年多之前 回复
csdnceshi73
喵-见缝插针 can only suggest to create a stackexchange question with some of the code and maybe a video showing the scroll problem...
5 年多之前 回复
csdnceshi61
derek5. the code sample is too long to post here but basically I am calling a function from viewWillAppear, if some condition is met, I will be scrolling the table view to the top and insert some rows with UIView.animation. The solution from fabb worked but this one did not really scroll
5 年多之前 回复
csdnceshi73
喵-见缝插针 some code example would help. Should work in swift.
5 年多之前 回复
csdnceshi61
derek5. I tried this solution in xcode 6 + swift. not really working. any possible reason where I am wrong or why this is not working any more?
5 年多之前 回复
csdnceshi73
喵-见缝插针 CGRectMake(0, 0, 0, 0) or CGRectZero isn't a visible rect. I would also say that [mainTableView setContentOffset:CGPointZero animated:YES]; is the prettier expression.
5 年多之前 回复
csdnceshi76
斗士狗 what is the explanation why 0,0 doesn't work?!
5 年多之前 回复
csdnceshi66
必承其重 | 欲带皇冠 Thanks! Been searching (on and off) for several days for this.
5 年多之前 回复
csdnceshi72
谁还没个明天 helped me too.Very good answer
6 年多之前 回复
weixin_41568184
叼花硬汉 Thanks. Works like a charm.
6 年多之前 回复
csdnceshi59
ℙℕℤℝ Note, you will want animated:NO if you run this in scrollToRowAtIndexPath: so as to make the table start in the correct position. Hope it helps!
6 年多之前 回复
csdnceshi67
bug^君 Using this code to go at some uiview in scroll: [scrollView scrollRectToVisible:CGRectMake(0, yourview.frame.origin.y, 1, 1) animated:YES];
接近 7 年之前 回复
csdnceshi68
local-host I first tried this with CGRectZero, which is equivalent to CGRectMake(0, 0, 0, 0). This does not work, but oddly the above does. I guess it needs a positive width and height. Thank you.
7 年多之前 回复
csdnceshi77
狐狸.fox thanks. I just added that to my 'scrollToRowAtIndexPath' line and scrolling works fine now.
8 年多之前 回复
csdnceshi52
妄徒之命 Worked for me too, even with a tableHeaderView
接近 9 年之前 回复
csdnceshi79
python小菜 Thank you, this helped.
11 年多之前 回复

I prefer

[mainTableView setContentOffset:CGPointZero animated:YES];

If you have a top inset on your table view, you have to subtract it:

[mainTableView setContentOffset:CGPointMake(0.0f, -mainTableView.contentInset.top) animated:YES];
csdnceshi73
喵-见缝插针 On iOS 11 you should consider using -scrollView.adjustedContentInset.top instead.
2 年多之前 回复
weixin_41568196
撒拉嘿哟木头 tried catlan's answer but that one did not work. this answer worked well :P
5 年多之前 回复
csdnceshi72
谁还没个明天 It works but doesn't take the 64px offset in regard
5 年多之前 回复
csdnceshi70
笑故挽风 This is what I tried first. Strangely it didn't work, which is what sent me here. scrollRectToVisible does work.
接近 7 年之前 回复
weixin_41568131
10.24 The solution to my previous comment: [tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];
7 年多之前 回复
weixin_41568131
10.24 This is indeed a clear code, but it does not work when your tableView has non-zero contentInset from the top. For example: tableView.contentInset = UIEdgeInsetsMake(5.0f, 0.0f, 250.0f, 0.0f);. If that is the case, in your code the tableView scrolls to (0.0f, 5.0f).
7 年多之前 回复
csdnceshi68
local-host This is the best way to use when you have table header or footer views and want them to be included too.
大约 8 年之前 回复
csdnceshi57
perhaps? Tomato, tomato. Hmm... That doesn't come across very clearly in writing.
8 年多之前 回复

Swift:

tableView.setContentOffset(CGPointZero, animated: true)

I've encountered an issue calling trying some of the methods on an empty tableView. Here's another option for Swift 4 that handles empty tableviews.

extension UITableView {
  func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
    return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section)
  }

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

Usage:

// from yourViewController or yourTableViewController
tableView.scrollToTop()

Swift 4:

This works very well:

//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)
weixin_41568184
叼花硬汉 Thank you. It will get you to the first cell. However, it doesn't show the table view header.
2 年多之前 回复
csdnceshi52
妄徒之命 I have both a plain and a UITableViewStyleGrouped (headers scrolls with the contents) and this code works. Be sure you are in the main thread and you launch this code after the view appear (viewDidAppear). If you still have problems try to put the code inside this: DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: { // the code }
2 年多之前 回复
weixin_41568184
叼花硬汉 Not if you have a tableHeaderView in your tableView and it's inline (scrolls with the content)
2 年多之前 回复

Adding on to what's already been said, you can create a extension (Swift) or category (Objective C) to make this easier in the future:

Swift:

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

Any time you want to scroll any given tableView to the top you can call the following code:

tableView.scrollToTop(animated: true)

Swift :

if you don't have tableView header :

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

if so :

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

Since my tableView is full of all kinds of insets, this was the only thing that worked well:

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)
}
csdnceshi69
YaoRaoLov great answer, appreciate it
大约 3 年之前 回复
csdnceshi66
必承其重 | 欲带皇冠 this was more useful to me
大约 3 年之前 回复

I prefer the following, as it takes into account an inset. If there is no inset, it will still scroll to the top as the inset will be 0.

tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
csdnceshi56
lrony* This was the part I was missing.
大约 3 年之前 回复

It's better to not use NSIndexPath (empty table), nor assume that top point is CGPointZero (content insets), that's what I use -

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

Hope this helps.

共30条数据 1 3 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐