Search code examples
iphoneuiscrollviewzoomingscale

UIScrollView with multiple zoom levels?


Is there a way that I can control which subviews of a UIScrollView are scaled and which are not?

For example, I have a map as the bottom layer (not MapKit, just a flat image) which can be zoomed and panned. Depending on user selections, markers are dropped on the map to indicate specific buildings/places etc. These markers are are also UIImageView, using pixel co-ordinates of the map image (eq Building X is at (934, 842), marker is placed here). Zoomed out however these markers are somewhat difficult to see as they also scale/zoom out to the same level as the map.

So is there a way that I can tell the UIScrollView NOT to scale the marker images, but still allow it to pan/reposition them when the map image is zoomed?


Solution

  • I think the method you may be looking for is the UIScrollViewDelegate's

    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

    This lets you return the view which you want the zoom to be applied to, in your case this will be the background map image.

    If you don't want the markers to be scaled at the same time, you will need to add the markers directly as subviews of the UIScrollView, instead of adding them as subviews of your background map UIImageView.

    As you mentioned, the markers are placed relatively to the map background UIImageView, this means if you add the markers to the UIScrollView instead, they won't be placed in the same position on the map once you change the scroll.

    To solve this, you will need to calculate the equivalent coordinates relative to the UIScrollView.

    While this may seem rather daunting, it is actually quite trivial to do once you know the zoom factor.

    To get the zoom factor, use the UIScrollViewDelegate method

    - (void)scrollViewDidZoom:(UIScrollView *)scrollView
    

    Then you can get the zoom factor by calling :

    scrollView.zoomScale
    

    and recalculate the marker coordinates by applying this zoomScale to the original values, and reposition your markers accordingly.

    Reference:

    UIScrollView Class Reference

    UIScrollViewDelegate Protocol Reference

    Hope this helps :)