ContentOffset in UIScrollView after rotation of iPhone

uiimageviewuiscrollview

I have an UIImageView in an UIScrollView and I have some trouble with the contentOffset property. From Apple's reference, this is defined as:

contentOffset: The point at which the origin of the content view is offset from the origin of the scroll view.

For example, if the image is at the upper left corner of the screen as below then the contentOffset would (0,0):

   _________
   |IMG    |
   |IMG    |
   |       |
   |       |
   |       |
   |       |
   ---------

For device rotation I have the following setting:

 scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
       UIViewAutoresizingFlexibleHeight);

 imageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
       UIViewAutoresizingFlexibleHeight);

 imageView.contentMode = UIViewContentModeCenter;  
    scrollView.contentMode = UIViewContentModeCenter;

This will make everything rotate around the center of the screen.
After rotating the screen, then screen will then look like this:

    ______________
    |       IMG  |
    |       IMG  |
    |            |
    --------------

My problem is that if I now read of contentOffset, it is still (0,0). (If I move the UIImage in landscape mode, the value of contentOffset is updated, but it is computed with respect to the wrong origin.)

Is there a way to compute the coordinates for the UIImage with respect to the upper left corner of the screen. contentOffset only seems to return this value when the screen is in the initial orientation of the view.

I have tried to read self.view.transform and scrollView.transform, but they are always the identity.

Best Answer

Here is one way to do this: For the scrollview set

scrollView.autoresizingMask =(UIViewAutoresizingFlexibleWidth 
                                     | UIViewAutoresizingFlexibleHeight);

scrollView.contentMode = UIViewContentModeTopRight;

The UIViewContentModeTopRight mode will keep the upper left corner at coordinate (0,0) even if the rotation behaviour is not correct. To get the same rotation behaviour as in UIViewContentModeCenter add

    scrollView.contentOffset = fix(sv.contentOffset, currentOrientation, goalOrientation);

into willAnimateRotationToInterfaceOrientation. fix is the function

CGPoint fix(CGPoint offset, UIInterfaceOrientation currentOrientation, UIInterfaceOrientation goalOrientation) {

CGFloat xx = offset.x;
CGFloat yy = offset.y;

CGPoint result;

if (UIInterfaceOrientationIsLandscape(currentOrientation)) {

    if (UIInterfaceOrientationIsLandscape(goalOrientation)) {
        // landscape -> landscape
        result = CGPointMake(xx, yy);
    } else {
        // landscape -> portrait
        result = CGPointMake(xx+80, yy-80);
    }
} else {
    if (UIInterfaceOrientationIsLandscape(goalOrientation)) {
        // portrait -> landscape
        result = CGPointMake(xx-80, yy+80);
    } else {
        // portrait -> portrait
        result = CGPointMake(xx, yy);
    }
}
return result;
}

The above code will make the scrollview rotate around the center of the screen and also ensure that the upper left corder is always are coordinates (0,0).

Related Topic