Search code examples
iosiphoneuiimageviewautolayoutuiinterfaceorientation

Frame of transformed UIView mess up after multiple orientation changes


I have an app with a photo library viewer. In the app you can select a photo and using gestures scale and pan around the photo. I do this by changing the affine transform of the UIImageView containing the photo. The app also supports changing phone orientations. In some situations the calculation of the frame of the UIImageView on orientation change seems to be wrong. The following in general will cause the frame size to be wrongly calculated.

  • Set UIImageView with identity transform
  • Set view transform so we are scaling about a pinch gesture
  • Rotate phone from portrait to landscape
  • Apply a new transform to the view to scale about a different point in the image
  • Rotate phone from landscape to portrait
  • set transform back to identity

After this the UIImageView frame is different from what it was originally so the image looks scaled.

The autoresizing flags for the UIImageView are .flexibleWidth and .flexibleHeight. Is there something I can do to avoid this. It looks like LayoutSubviews doesn't cope very well with scaled UIViews. I tried removing the scale in viewWillLayoutSubviews() and re-applying in viewDidLayoutSubviews() but this didn't help.


Solution

  • Transforms do not change the bounds of your view; they are applied after autolayout is calculated. The transforms should be used for transitory things like animation and not for positioning and sizing your UI (this would for instance also give you incorrect coordinates for things like panGestureRecognizer).

    I think you are better off putting your imageView into a UIScrollView than messing with the transforms. UIScrollView already handles panning and pinch to zoom so all you have to do is handle scrollViewDidZoom and adjust your constraints accordingly. here is an example.