UIScrollView & setContentOffset random scrolling on iOS 4

We encountered a nasty bug with UIScrollView while porting app to iOS 4. The following code worked just fine on old iPhone versions:

 
// Update view with new content
[self updateContent:...]

// We want the view to be on top every time the it is shown
[scrollView setContentOffset:CGPointMake(0,0) animated:NO];

// And set the correct size to enable scrolling.
// contentHeight is updated when setting the content of subviews.
[scrollView setContentSize:CGSizeMake(self.view.frame.size.width, contentheight)];

No problems. But on iOS 4 the UIScrollView decided to do something fancy and scroll to random position depending on where it was left when the view was hidden the last time. After spending expensive manpower to solve the issue by trying numerous ways to tell the scrollView to go to top using setContentOffset, the final solution was simple yet very different what one might think: to fix this we had to set the contentSize to zero before updating any of the content.

// Need to do this on iOS 4 or the view scrolls to random position
[scrollView setContentSize:CGSizeMake(0,0)];

// Update view with new content
[self updateContent:...]

// We want the view to be on top every time it is shown
[scrollView setContentOffset:CGPointMake(0,0) animated:NO];

// And set the correct size to enable scrolling.
// contentHeight is updated when setting the content of subviews.
[scrollView setContentSize:CGSizeMake(self.view.frame.size.width, contentheight)];

Hopefully there is more logical way to update scrollview’s content without being scrolled around.

2 thoughts on “UIScrollView & setContentOffset random scrolling on iOS 4

  1. Thanks. Was banging my head against the wall too long with this problem and now it is solved!

  2. I think I have a similar problem. For me the the set content offset method only works when I have a table view which fills the whole screen. When my table view has only few cells then it doesn’t work. I’m using a UITableViewController and I have a search box on top of my table view. I need to show/hide the search at certain scrolled positions. The code I currently have now is,

    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {

    CGPoint point = scrollView.contentOffset ;

    if ((point.y > 22) && (point.y 0 && point.y < 22) {
    [self.tableView setContentOffset:CGPointMake(0, 0) animated:YES];
    }

    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>