5

I have a UIScrollView in which vertical only scrolling is enabled. I'm displaying a grid of buttons (similar to the photo viewer image grid). The grid has to be drawn differently based on screen orientation, so that all of the screen real estate is used. Given the size of my buttons, I can fit 3 per row in portrait, and 4 per row in landscape.

I reposition all of the buttons in: willRotateToInterfaceOrientation:duration and then call: setContentSize: on my UIScrollView. Everything seems to work just fine, with the exception of the auto-scrolling that occurs after the call to SetContentSize:. In other words, let's say I was in portrait, and scrolled 3/4 of the way down the list, when I rotate to landscape, it auto-scrolls all the back up to the top.

The interesting thing is, in the same scenario, if I were to do a small flick scroll up or down, and then immediately rotate the device, the scroll view redraws correctly, and retains the current scroll position!

So, to be clear, the culprit here seems to be SetContentSize:, but obviously I have to call that for the scroll view to scroll correctly.

Any ideas on how I can retain the current scroll position?

Thanks!

bpatrick100
  • 1,261
  • 1
  • 15
  • 23

2 Answers2

1

You might try implementing the UIScrollViewDelegate method scrollViewShouldScrollToTop:, which tells the caller whether to scroll to the top or not. You may have to have some flag in your delegate that indicates if a rotation is underway or not, because under normal conditions you may actually want the ability to tap the status bar and have the scroll view scroll to the top.

If, on the other hand, you don't ever want the scroll view to scroll to the top automaticlly, simply implement that delegate method and have it return NO.

Mark Granoff
  • 16,878
  • 2
  • 59
  • 61
  • This doesn't work. This has the same effect as using: scrollView.scrollsToTop = NO; Which, yes, prevents the auto-scroll to top when tapping the status bar, however, the behavior I've described in my original question still persists... – bpatrick100 Apr 14 '11 at 17:36
  • Another thought: Before you call `setContentSize:`, remember where in the content you are, then after that call, call `setContentOffset:`. It may be the case that when you set the content size, the content offset is reset purposefully to (0,0). You may have reset the content size to something that no longer includes whatever the content offset was before resetting the size. So the SDK is perhaps protecting itself and the user experience to some degree by ensuring that something is always shown after a content size change. – Mark Granoff Apr 14 '11 at 17:45
0

I had this problem, just did this and it works well for me

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    //calculate percentage down scrollview currently at
    float c = self.scrollView.contentOffset.y / self.scrollView.contentSize.height;

    //reposition subviews in the scrollview
    [self positionThumbnails:toInterfaceOrientation];

    //set the new scrollview offset to the same percentage, 
    // using the new scrollview height to calculate
    self.scrollView.contentOffset = 
          CGPointMake(0, c * self.scrollView.contentSize.height);
}

In my case, I have a scrollview with a fixed width to device size, and variable height

Steven Stefanik
  • 486
  • 3
  • 9