5

In iOS 7, I use the following code to scroll to the top of my UITableView. You have to account for the overlap of the translucent status bar and navigation bar.

[tableView 
    setContentOffset:CGPointMake(
        0.0, 
        -tableViewController.topLayoutGuide.length
    ) 
    animated:YES
];

This works only works after the first time you call it. On the first time you call it, my table gets scrolled much farther than it should, showing a lot of white space. Additionally, the UIRefreshControl appears frozen. You have to nudge the table a little to make it bounce back to the true top. Afterwards, you can call this code as many times as you want and it behaves as you'd expect it.

enter image description here enter image description here

I've tried other ways, but they all have problems. The iOS 6 way behaves just as oddly on the first call. Although it doesn't jump a huge amount on subsequent calls, they are not correct because it scrolls to 64.0 points below the top of the table because we forgot to account for the status and navigation bar.

[table setContentOffset:CGPointZero animated:YES];

I've also tried scrolling to the first cell, but it doesn't scroll to the very top in one call. It will only scroll up one page's worth every time you call it.

[tableView 
    scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 
    atScrollPosition:UITableViewScrollPositionTop 
    animated:YES
];
Pwner
  • 3,714
  • 6
  • 41
  • 67
  • Try this answer http://stackoverflow.com/questions/724892/uitableview-scroll-to-the-top?rq=1 – Duncan Groenewald Nov 26 '13 at 01:36
  • 1
    @DuncanGroenewald `[tableView scrollRectToVisible:CGRectMake(0.0, 0.0, 1.0, 1.0) animated:YES]` only scrolls up one screen-full at a time. I have to call it so many times to scroll to the very first cell. Maybe it's just my code situation ... I don't know ... – Pwner Nov 26 '13 at 01:42

8 Answers8

17

Try this one:

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

In SWIFT

    let top = NSIndexPath(forRow: NSNotFound , inSection: 0)
    tableView.scrollToRowAtIndexPath(top, atScrollPosition: .Bottom, animated: true)

Swift 4.0 and above

 let top = NSIndexPath(row: NSNotFound, section: 0)
 tableView.scrollToRow(at: top as IndexPath, at: .bottom, animated: true)
Dhaval Bhadania
  • 3,090
  • 1
  • 20
  • 35
  • Like all the other attempts, this only scrolls up one screen's worth. I have to call it so many times if I'm scrolled down multiple screens. – Pwner Nov 26 '13 at 22:43
6

i looked at other answers and found the following solution that worked for me.

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

Hope, it solves your problem.

Vinay Jain
  • 2,644
  • 3
  • 26
  • 44
2

it's not "magic". The 64 offset is for status bar(20 points) and navigation bar(44 points) heights. If the scrollview have offset of 0 and you also have status bar + navigation bar, it would be under these objects and you will see -64.0 of your original content. In storyboard there is an option "Adjust scroll view insets" and this is checked by default

shota
  • 388
  • 1
  • 8
0

Try:

[tableView
    setContentOffset:CGPointMake(
        tableView.contentOffset.x,
        -tableView.contentInset.top
    )
    animated:YES
];
skedastik
  • 654
  • 7
  • 14
  • This only scrolls up a screen's worth of cells, not the entire height of the table. – Pwner Nov 26 '13 at 03:13
  • Sounds like aberrant behavior to me. Per Apple's documentation, setting contentOffset should take you to that specific offset, period. Are you using a vanilla UITableView? – skedastik Nov 26 '13 at 03:48
0

Please try this:

- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;

The sample is like this:

[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:0 animated:YES];
banumelody
  • 21
  • 3
0

In Objective-C

[mainTableView setContentOffset:CGPointZero animated:YES];

And in Swift:

mainTableView.setContentOffset(CGPointZero, animated:true)
Vatsal Raval
  • 311
  • 1
  • 9
0

In Objective C

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

In Swift

var scrollIndexPath: NSIndexPath = NSIndexPath(forRow:NSNotFound , inSection: 0)
self.tableview.scrollToRowAtIndexPath(scrollIndexPath, atScrollPosition: UITableViewScrollPosition.top, animated: true)
Sabby
  • 403
  • 3
  • 15
-1

iOS scrollview is behaving a bit oddly. The 64.0 offset was added "magically" to the first scrollview in the view hierarchy "the first time" as you mentioned. I haven't figured out why this was happening. At the moment I only had a really hackish solution: you can add a dummy scroll as the first scrolling in the view hierarchy, with height set as 0. After that, you solution should work as usual.![enter image description here][1]

screenshot : https://i.stack.imgur.com/4Rky8.jpg

Hope this helps.

Anyone else know why this is happening in the first place ?

noooooooob
  • 1,872
  • 3
  • 21
  • 27