1
votes

I'm using a UIScrollView with multiple UIScrollViews as subview, each containing a UIImageView to display a picture.
The app itself only supports portrait orientation, but I do want the image views to rotate when the device is rotated (observing UIDeviceOrientationDidChangeNotification).
Rotation of the image views is done with an animated setTransform: using both CGAffineTransformScale and CGAffineTransformMakeRotation.
Zooming the image views is done by returning the image view from viewForZoomingInScrollView: for the scrollview containing the image view.

This is all working great, except for one thing: when the image view is rotated, I am no longer able to zoom. Debugging shows viewForZoomingInScrollView: is being called, but scrollViewDidZoom: is not.

Does anyone have any idea of what might be causing this problem?

1
But you are able to zoom when it is in portrait? If you rotate to landscape, then back to portrait, are you able to zoom again?mbuc91
Yes, I can zoom when in portrait, and yes I can zoom again when returning to portait.René

1 Answers

7
votes

Fixed it by applying the transformations to the UIScrollView (containing the UIImageView), instead of the UIImageView itself.

Just applying the transformations to the UIScrollView didn't work well enough. It would put the rotated image inside a smaller view and zooming did not use the available screen space.

I finally managed to fix this though, so here's how.

Requirements

  • A horizontally scrolling list of full-screen pictures
  • Rotating the device must not rotate the app, but must rotate the shown picture
  • Must be able to zoom pictures, both when holding the device in portrait and landscape orientation

How I implemented it

One main UIScrollView with height equal to screen height, and width equal to screen width * picture count. Paging enabled.
This main UIScrollView contains a subview for each picture. Each subview looks like this:
UIScrollView > UIView > UIImageView

The UIScrollView has the size of the screen, and its origin.x property is 0 for the first subview, and increased with the screen width for each subsequent UIScrollView. The result is a main UIScrollView, with all the sub UIScrollViews next to eachother like this (without the spacing):

┌────────────────────┐
│┌───┐┌───┐┌───┐┌───┐│
││ 1 ││ 2 ││ 3 ││ 4 ││
││   ││   ││   ││   ││
│└───┘└───┘└───┘└───┘│
└────────────────────┘

To fix the rotation problem, the UIImageView is no longer a direct subview from the UIScrollView, but is now embedded inside a container UIView.
The viewForZoomingInScrollView: method of the main UIScrollView delegate now returns the container UIView for the visible picture, so this container UIView will be used for zooming. Rotation of the image views is still done with an animated setTransform: using both CGAffineTransformScale and CGAffineTransformMakeRotation.

My guess that the implementation without the container UIView did not work, was because the UIImageView can no longer be transformed by the main UIScrollView, when there's already a transform applied to it.