Rogare February 2016

Setting contentOffset after zooming and redrawing UIScrollView content

I have a UIScrollView that contains a view which redraws itself during zooming. The scaling works great, but setting the contentOffset isn't working. Here is the code

func scrollViewDidZoom(scrollView: UIScrollView) {

    // Get relative position of content view
    let pX = (scrollView.contentOffset.x + scrollView.frame.width / 2.0) / scrollView.contentSize.width
    let pY = (scrollView.contentOffset.y + scrollView.frame.height / 2.0) / scrollView.contentSize.height

    // Rescale and redraw content view        
    contentView.frame=CGRect(x: 0,
        y: 0,
        width: contentView.frame.width * scrollView.zoomScale,
        height: contentView.frame.height * scrollView.zoomScale)
    contentView.scale *= scrollView.zoomScale

    // Recalculate content offsets so that relative position of content is the same as before
    let nX = contentView.frame.width * pX - scrollView.frame.width / 2.0
    let nY = contentView.frame.height * pY - scrollView.frame.height / 2.0

    // Reset zoom level of scroll view and content offsets
    scrollView.setZoomScale(1.0, animated: false)
    scrollView.setContentOffset(CGPoint(x: nX, y: nY), animated: false)

The result is that content view just expands in the positive x and y direction (down and to the right) when it should be zooming in. I've seen some other potential solutions for scrollViewDidEndZooming, but even those aren't working for my case. Any idea where I've gone wrong here?


Rogare February 2016

The problem here was AutoLayout, or rather my use of frames instead of constraints. The problem was solved by a) creating a width constraint property and then editing its constant value when needed, and b) implementing my own zooming behaviour instead of the default UIScrollView's.

Post Status

Asked in February 2016
Viewed 1,662 times
Voted 5
Answered 1 times


Leave an answer