views:

101

answers:

1

I'm having difficulties getting a tiled UIScrollView to zoom in and out correctly with pinch zooming. The issue is that when a pinch-zoom occurs, the resulting view is usually not centered in the same region.

Details: The app starts with a tiled image that is 500x500. If a user zooms in, it will snap to 1000x1000 and the tiles will redraw. For all the zoom affects, etc. I am just letting the UIScrollView do it's thing. When scrollViewDidEndZooming:withView:atScale: is called, I redraw the tiles (like you can see in many examples and other questions here).

I think that I've drilled the problem down to calculating the center of the view correctly when I get to scrollViewDidEndZooming:withView:atScale: (I can center on a known point fine after I redraw).

What I'm currently using:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
    // as an example, create the "target" content size
    CGSize newZoomSize = CGSizeMake(1000, 1000);

    // get the center point
    CGPoint center = [scrollView contentOffset];
    center.x += [scrollView frame].width / 2;
    center.y += [scrollView frame].height / 2;

    // since pinch zoom changes the contentSize of the scroll view, translate this point to 
    // the "target" size (from the current size)
    center = [self translatePoint:center currentSize:[scrollView contentSize] newSize:newZoomSize];

    // redraw...
}

/*
    Translate the point from one size to another
*/
- (CGPoint)translatePoint:(CGPoint)origin currentSize:(CGSize)currentSize newSize:(CGSize)newSize {
    // shortcut if they are equal
    if(currentSize.width == newSize.width && currentSize.height == newSize.height){ return origin; }

    // translate
    origin.x = newSize.width * (origin.x / currentSize.width);
    origin.y = newSize.height * (origin.y / currentSize.height);
    return origin;
}

Does this seem correct? Is there a better way? Thanks!

A: 

The way I have solved this so far is to store the initial center point of the view when the zoom starts. I initially saving this value when the scrollViewDidScroll method is called (and the scroll view is zooming). When scrollViewDidEndZooming:withView:atScale: is called, I use that center point (and reset the saved value).

Rob