views:

2203

answers:

2

I have a UIScrollView that contains an image and a segmented control that allows the user to switch the image inside of the ScrollView. If I just swap the image out inside of the UIImageView, it will display the new image in the zoomed-in state. How do I reset the UIScrollView back to its un-zoomed-in state?

A: 

If you're not redrawing your view on the completion of the pinch zooming event, then the zoom factor is being set by the transform property of the view you return from the viewForZoomingInScrollView: delegate method. To reset this zoom, set the value of the view's transform property to CGAffineTransformIdentity.

Beware, though, that your next pinch-zooming operation will start where the previous pinch-zoom left off (that is, your new scale will be ignored). To work around this, you may need to implement some of what I describe here.

Brad Larson
so when I switch the images, I'm doing the following: imageView.transform = CGAffineTransformIdentity;Is that what you meant? Because it doesn't seem to effect it.
Bdebeez
How are you switching your images? Is your content view for your UIScrollView the UIImageView? Is this UIImageView what you then return from viewForZoomingInScrollView:? This should work for the main subview of the scroll view.
Brad Larson
Yes, that's exactly how I'm doing it. The scoll view contains one subview - the UIImageView - and I'm setting the .image property on that to a different UIImage when the selection changes.
Bdebeez
That's strange, it should work. Do you also change the contentSize of the scroll view to match your UIImageView after the image has been swapped out? That might help.
Brad Larson
+2  A: 

I have a detailed discussion of how (and why) UIScrollView zooming works at github.com/andreyvit/ScrollingMadness/.

(The link also contains a description of how to programmatically zoom UIScrollView, how to emulate Photo Library-style paging+zooming+scrolling, an example project and ZoomScrollView class that encapsulates some of the zooming magic.)

Quote:

UIScrollView does not have a notion of a “current zoom level”, because each subview it contains may have its own current zoom level. Note that there is no field in UIScrollView to keep the current zoom level. However we know that someone stores that zoom level, because if you pinch-zoom a subview, then reset its transform to CGAffineTransformIdentity, and then pinch again, you will notice that the previous zoom level of the subview has been restored.

Indeed, if you look at the disassembly, it is UIView that stores its own zoom level (inside UIGestureInfo object pointed to by the _gestureInfo field). It also has a set of nice undocumented methods like zoomScale and setZoomScale:animated:. (Mind you, it also has a bunch of rotation-related methods, maybe we're getting rotation gesture support some day soon.)

However, if we create a new UIView just for zooming and add our real zoomable view as its child, we will always start with zoom level 1.0. My implementation of programmatic zooming is based on this trick.

Andrey Tarantsov