UIScrollView zoom centered with content layout guide

In WWDC 2017 video 201 https://developer.apple.com/videos/play/wwdc2017/201/ there's a claim that the new content layout guide solves the problem of zooming while staying centered: you center the content view in the content layout guide.

I've tried this and I can't get it to work. I can zoom, but there is still a tendency for the content view to end up at the top left. Has anyone figured out what's meant by that claim?

Replies

I also tried it and I couldn't figure out what it meant either. Surely you would only want the content centered if it's smaller than the scroll view, and zooming around the pinch center if it's larger. If nothing else, I don't see how you can achieve both of those behaviors with a single layout constraint.


OTOH, the audience applauded, so maybe they knew what was meant.

Oh, I know perfectly what she meant, and so did the audience. And we all applauded because this has always been so hard to achieve in the past and we thought it was true that now it would be easy.


Your objection is spot on. Using her code from 2010, I always do what she's describing like this:


class MyScrollView : UIScrollView {
    override func layoutSubviews() {
        var which : Int {return 1}
        switch which {
        case 1:
            print("layout")
            super.layoutSubviews()
            if let v = self.delegate?.viewForZooming?(in:self) {
                let svw = self.bounds.width
                let svh = self.bounds.height
                let vw = v.frame.width
                let vh = v.frame.height
                var f = v.frame
                if vw < svw {
                    f.origin.x = (svw - vw) / 2.0
                } else {
                    f.origin.x = 0
                }
                if vh < svh {
                    f.origin.y = (svh - vh) / 2.0
                } else {
                    f.origin.y = 0
                }
                v.frame = f
            }
        default:break
        }
    }
}

Well, as you rightly say, that code only takes over when we zoom out so far that the content view is smaller than the scroll view. It's hard to see how one constraint configuration is going to do _that_, unless it involves inequalities that she never mentioned.

But in any case, in my experiments, the content view doesn't stay centered at all. It's weird, because logging shows that the content layout guide is staying the same size, so you would think its center would not move.

My content view inside needs to be smaller than the scroll view. I failed to center the content view when zoomed, either with the scroll view's contentLayoutGuide, or by constraining the content view's 4 anchors with the scroll view's anchors, with proper constants. The suggested constraints in Xcode 9's Interface Builder are 4 edge achors of the content view to the scroll view, and the center X and Y anchors to the scroll view. It works if the constraint constants are all 0, i.e., the content view occupies the whole scroll view. However, it doesn't work since my content view must be smaller. Is there a good solution?


It's a common need to center the zoomed content view in a scroll view, and avoid any extra margins on the edges when zoomed in. iOS should have a good solution, and a simple one. If the solution is complex, why not offer a Bool property in UIScrollView to achive this automatically?