I successfully implemented a pinch a zoom of a view. However, the view doesn't position itself where I wished it to be. For the stackoverflowers with an iPad, I would like my view to be centered like on the iPad Photos.app : when you pinch&zoom on an album, the photos present themselves in a view that is expanding. This view is approximately centered with the top right hand corner on the first finger and the bottom left hand finger on the other finger. I mixed it with a pan recognizer, but this way the user always has to pinch, and then pan to adjust.
Here are so graphic explanation, I could post a video of my app if that's unclear (no secret, i'm trying to reproduce the Photos.app of the iPad...)
So for an initial position of the fingers, begining zooming :
This is the actual "zoomed" frame for now. The square is bigger, but the position is below the fingers
Here is what I would like to have : same size, but different origin.x and y :
(sorry about my poor photoshop skills ^^)
iOS UIGestureRecognizer UIPinchGestureRecognizer Pinches are a two fingered gesture where the fingers move closer or farther from each other. This gesture is generally used for resizing a view.
The pinch gesture is used for performing interactive zoom and is implemented with the PinchGestureRecognizer class. A common scenario for the pinch gesture is to perform interactive zoom of an image at the pinch location. This is accomplished by scaling the content of the viewport, and is demonstrated in this article.
A pinch gesture is a continuous gesture that tracks the distance between the first two fingers that touch the screen. Use the UIPinchGestureRecognizer class to detect pinch gestures.
What is pinch-to-zoom? Pinch-to-zoom is when a user uses two fingers and pinches to zoom in or out on their mobile device. While it wasn't present on the original touchscreen phones, pinch-to-zoom is now a nearly universal motion for adjusting size on touchscreen devices.
You can get the CGPoint
of the midpoint between two fingers via the following code in the method handlingPinchGesture
.
CGPoint point = [sender locationInView:self];
My whole handlePinchGesture
method is below.
/* instance variables CGFloat lastScale; CGPoint lastPoint; */ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender { if ([sender numberOfTouches] < 2) return; if (sender.state == UIGestureRecognizerStateBegan) { lastScale = 1.0; lastPoint = [sender locationInView:self]; } // Scale CGFloat scale = 1.0 - (lastScale - sender.scale); [self.layer setAffineTransform: CGAffineTransformScale([self.layer affineTransform], scale, scale)]; lastScale = sender.scale; // Translate CGPoint point = [sender locationInView:self]; [self.layer setAffineTransform: CGAffineTransformTranslate([self.layer affineTransform], point.x - lastPoint.x, point.y - lastPoint.y)]; lastPoint = [sender locationInView:self]; }
Have a look at the Touches sample project. Specifically these methods could help you:
// scale and rotation transforms are applied relative to the layer's anchor point // this method moves a gesture recognizer's view's anchor point between the user's fingers - (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { UIView *piece = gestureRecognizer.view; CGPoint locationInView = [gestureRecognizer locationInView:piece]; CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview]; piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height); piece.center = locationInSuperview; } } // scale the piece by the current scale // reset the gesture recognizer's rotation to 0 after applying so the next callback is a delta from the current scale - (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer { [self adjustAnchorPointForGestureRecognizer:gestureRecognizer]; if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) { [gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]); [gestureRecognizer setScale:1]; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With