2

This is my first post, so my apologies if I word any of this incorrectly. I will be happy to clarify if need be.

I have a pageViewController and each viewController it presents contains a scrollView which displays an imageView from an in-app photo gallery (very similar to enlarging a photo in the Photos app and then swiping through the collection of images). I've implemented zooming in and out through pinch gestures and generally everything is working, however, when I swipe from one image to the next, then back to the original, and then try swiping forward or backwards, the view gets "stuck". To illustrate this a bit better, say you select image 2 in the gallery. If you swipe to image 3, then swipe back to image 2, swiping towards either image 1 or image 3 shows a sliver of the image you're trying to get to and then snaps back to image 2.

A quick pinch to zoom the image out a bit and have it lock back into the width of the screen allows you to freely zoom forward or backwards again. I've tried adding some code in viewDidAppear to zoom the image out quickly and then let it snap back to the bounds of the screen to simulate this gesture, but as expected you can see the adjustment happening each time a new image is put on the screen and I'd like the swiping to be smooth.

Any ideas as to a way to fix this would be greatly appreciated. I've read into Apple's documentation regarding both scrollViews and pageViews as well as their associated delegates and datasources but haven't been able to find a source of this problem, though I may have simply overlooked something.

As stated above, please let me know if I can offer any clarification to the issue at hand. Thanks in advance.

bluewraith
  • 153
  • 1
  • 9

1 Answers1

2

I struggled with the same issue for a while, and tracked it down to zooming, and eventually an error in centering the content after zooming. Most of my post is in Swift (2.1), but the link to my main solution is in Obj-C. I have two answers:

You can set scrollView.bouncesZoom = false in your viewDidLoad() (or your Obj-C equivalent). This prevents the UIScrollView from being able to zoom past the minimum zoom scale, such that the user is unable to make the image smaller by pinching when the image is at the minimum zoom scale.

However, the much more elegant solution comes from https://stackoverflow.com/a/2887298/2490299. Originally, my centerScrollViewContents() (aka scrollViewDidZoom() in the linked answer) was:

func centerScrollViewContents() {
    let boundsSize = scrollView.bounds.size
    var contentsFrame =  imageView.frame

    if contentsFrame.size.width < boundsSize.width {
        contentsFrame.origin.x = (boundsSize.width - contentsFrame.width) / 2.0
    } else {
        contentsFrame.origin.x = 0.0
    }

    if contentsFrame.size.height < boundsSize.height {
        contentsFrame.origin.y = (boundsSize.height - contentsFrame.height) / 2.0
    } else {
        contentsFrame.origin.y = 0.0
    }

    imageView.frame = contentsFrame
}

Apparently centering the content by altering the frame caused this issue. For reference, the Swift equivalent to the answer linked above is:

func scrollViewDidZoom(scrollView: UIScrollView) {
  let offsetX = max((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0)
  let offsetY = max((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0)

  imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, 
                             scrollView.contentSize.height * 0.5 + offsetY)
}

Hopefully this helps you out if you happened to have the same issue I was; it sounds very similar.

Community
  • 1
  • 1
natec
  • 254
  • 1
  • 3
  • 16
  • Thanks for the detailed response, I had forgotten I posted this question here. I solved the problem several months ago and my solution was similar to yours. When I get a chance, I'll dig up the code and edit my question to show my approach. Thanks again for your answer. – bluewraith Jan 05 '16 at 15:01