7

I'm trying to get notified when UIScrollView is pinch zoomed out beyond its minimum zoom limit and is about to animate back, but I'm finding it very difficult. Is there a way I can do this with delegate methods alone or do I need to override UIScrollView's touch handling?

Alex Cio
  • 6,014
  • 5
  • 44
  • 74
Nick
  • 3,958
  • 4
  • 32
  • 47

4 Answers4

11

Use scrollViewDidZoom: and check if scrollView.zoomBouncing == YES. Then use zoomScale to determine which direction the view is bouncing.

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    if (scrollView.zoomBouncing) {
        if (scrollView.zoomScale == scrollView.maximumZoomScale) {
            NSLog(@"Bouncing back from maximum zoom");
        }
        else
        if (scrollView.zoomScale == scrollView.minimumZoomScale) {
            NSLog(@"Bouncing back from minimum zoom");
        }
    }
}
Gary Chapman
  • 418
  • 9
  • 20
2

You can use UIScrollView's scrollViewDidZoom delegate method to detect the moment it's about to animate back. You'll see scrollView.zoomScale drop below scrollView.minimumZoomScale while the view is being pinched. Then, as soon as the user releases their fingers, scrollViewDidZoom will be called once again with scrollView.zoomScale == scrollView.minimumZoomScale, but scrollView.zooming == NO.

Capturing this moment is fine and all, but attempting to do anything to preempt the bounce-back-to-minimumZoomScale animation seems to have really odd side effects for me. :(

Aamir
  • 16,329
  • 10
  • 59
  • 65
strawtarget
  • 1,059
  • 2
  • 9
  • 18
  • what if I want to capture a zoomScale other than minimumZoomScale, like `if !scrollView.zooming && scrollView.zoomScale < 0.6 {do something} ` – osrl Dec 24 '14 at 22:59
2

In Swift 4.0:

func scrollViewDidZoom(_ scrollView: UIScrollView) {
    if scrollView.zoomScale == scrollView.minimumZoomScale
    {
        print("zoomed out")
    }
}

This will be called exactly when the user has finished zooming and the zoomScale is at its minimum possible value, i.e. when the scroll view is zoomed out completely.

KhanKhuu
  • 177
  • 11
  • How can I detect the user pinching to zoom out, if they don't zoom out all the way? –  Aug 25 '21 at 20:55
  • @Daniel Springer that zoomScale attribute has all the info you need. It will be decreasing as they zoom out, so check to see if zoomScale has decreased without going all the way out (i.e. all the way to minimumZoomScale). If you still have issues ask the question and link it here, I can share an example of that – KhanKhuu Aug 26 '21 at 23:18
  • In order to check if it decreased, need I save the previous value to a variable of my own? –  Aug 26 '21 at 23:48
  • Yes exactly. There is nothing built into the scrollView that does this for you, so you would want to track it with your own variable. – KhanKhuu Aug 28 '21 at 02:31
  • Got it. Thanks! –  Aug 30 '21 at 22:41
0

I did it with UIPinchGestureRecognizer.

-(void)viewDidLoad{
    UIPinchGestureRecognizer *gestureRecognizer = 
     [[[UIPinchGestureRecognizer alloc] initWithTarget:self 
                                                action:@selector(pinched:)] 
                                                               autorelease];
    gestureRecognizer.delegate=self;
    [self.scrollView addGestureRecognizer:gestureRecognizer];
    //your code
}
-(void)pinched:(UIPinchGestureRecognizer*)gestureRecognizer{
    if(gestureRecognizer.state==UIGestureRecognizerStateEnded){
        //pinch ended
        NSLog(@"scale: %f",scrollView.zoomScale);
    }
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
        shouldRecognizeSimultaneouslyWithGestureRecognizer:
                          (UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}
Alex Cio
  • 6,014
  • 5
  • 44
  • 74
b123400
  • 6,138
  • 4
  • 27
  • 27