1

I have an image drawn using PaintCode. And that image has a Scale variable. on line marked "// A", I've edited the usual PaintCode generated code so that I can pass in a scale and have the image created at the correct height and width.

public class func imageOfMap(scale scale: CGFloat = 1) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(
        CGSizeMake(scale*1660, scale*1832), // A
        false, 0) 
    MapStyleKit.drawMap(scale: scale)

    let imageOfMap = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return imageOfMap
}

Now I have a UIImageView inside of a UIScrollView. And I have the scrollview contrained to the inside of my ViewController's view, and the imageview constrained to the inside of the scrollview, using autolayout constraints.

I've looked into "viewForZooming" and "scrollViewDidZoom", but those only use a CGAffineTransformScale on the image view. I've tried setting the correct image in "scrollviewDidZoom" and I've tried using my own pinch gesture recognizers, but my math must be wrong about some where but I don't know where.

Each time I zoom, I want to supply a new image the image view from PaintCode at the correct zoom level.

Further, I want the image to "stay in place" as one would expect when pinching to zoom in Google Maps or Apple Maps. Right now I'm trying to multiply the scrollView's contentOffset by a factor of the contentSize, the scrollView's frame and the current scale, and the image is jumping around alot when zooming.

I've done a lot of researching and tinkering and haven't been able to figure this out. So I'm finally asking here. Please help! Thank you for your time.

Daniel R
  • 312
  • 1
  • 9

1 Answers1

0

I was able to figure it out!

func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
    let newScale: CGFloat
    if scale <= scrollView.minimumZoomScale {
        newScale = scrollView.minimumZoomScale
    } else if scale >= scrollView.maximumZoomScale {
        newScale = scrollView.maximumZoomScale
    } else {
        newScale = scale
    }

    let offset = scrollView.contentOffset
    scrollView.zoomScale = 1.0
    imageView.image = MapStyleKit.imageOfMap(scale: newScale)
    scrollView.contentSize = contentSizeForScale(newScale)
    imageView.frame = CGRect(origin: CGPointZero, size: contentSizeForScale(newScale))


    scrollView.contentOffset = offset
}

func scrollViewWillBeginZooming(scrollView: UIScrollView, withView view: UIView?) {
    let offset = scrollView.contentOffset
    scrollView.zoomScale = imageView.scale
    imageView.image = MapStyleKit.imageOfMap(scale: 1.0)
    scrollView.contentSize = contentSizeForScale(1.0)
    imageView.frame = CGRect(origin: CGPointZero, size: contentSizeForScale(1.0))
    scrollView.contentOffset = CGPoint(x: imageView.scale*offset.x, y: imageView.scale*offset.y)
}

func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
    return imageView
}

Need to save the contentOffset in a temp variable before setting zoomScale on the scrollview

Edit: And contentSizeForScale of course returns a CGSize of what the image will be at a given scale!

Daniel R
  • 312
  • 1
  • 9