Pwner
Pwner

Reputation: 3785

How to scroll to the top of a UITableView in iOS 7

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
];

Upvotes: 5

Views: 12457

Answers (8)

Dhaval Bhadania
Dhaval Bhadania

Reputation: 3089

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)

Upvotes: 17

Sabby
Sabby

Reputation: 403

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)

Upvotes: 0

Vatsal Raval
Vatsal Raval

Reputation: 313

In Objective-C

[mainTableView setContentOffset:CGPointZero animated:YES];

And in Swift:

mainTableView.setContentOffset(CGPointZero, animated:true)

Upvotes: 0

shio
shio

Reputation: 408

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

Upvotes: 2

banumelody
banumelody

Reputation: 21

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];

Upvotes: 0

Vinay Jain
Vinay Jain

Reputation: 2634

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.

Upvotes: 6

noooooooob
noooooooob

Reputation: 1890

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.sstatic.net/4Rky8.jpg

Hope this helps.

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

Upvotes: -1

skedastik
skedastik

Reputation: 654

Try:

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

Upvotes: 0

Related Questions