A large-scale conversion leaves the start (0, 0) untouched. To scale a view around a specific point, you must first translate that point to the origin, then apply the scale, and then translate back.
- (IBAction)pinchGestureDidFire:(UIPinchGestureRecognizer *)pinch {
First, we get a view that is pinched.
UIView *pinchView = pinch.view;
To calculate the center of the pinch, we need the midpoint of the view boundaries, so we also get the borders:
CGRect bounds = pinchView.bounds;
The center is based on the center of gravity of the touch, which we get as follows:
CGPoint pinchCenter = [pinch locationInView:pinchView];
But we really need a pinch offset relative to the center of the view, because the default view transformation is relative to the center of the view. (You can change this by changing the presentation of layer.anchorPoint .)
pinchCenter.x -= CGRectGetMidX(bounds); pinchCenter.y -= CGRectGetMidY(bounds);
Now we can update the view transformation. First we get its current conversion:
CGAffineTransform transform = pinchView.transform;
Then we update it to translate the pinch center to the beginning:
transform = CGAffineTransformTranslate(transform, pinchCenter.x, pinchCenter.y);
Now we can apply the scale:
CGFloat scale = pinch.scale; transform = CGAffineTransformScale(transform, scale, scale);
Then translate the view back:
transform = CGAffineTransformTranslate(transform, -pinchCenter.x, -pinchCenter.y);
Now we can update the view using a modified transformation:
pinchView.transform = transform;
Finally, we reset the gesture recognition scale since we applied the current scale:
pinch.scale = 1.0; }
Demo:

Please note that in the simulator you can hold the (alt) option for hard pressing. Holding shift (while holding) moves two touches together.
Here is all the code to copy / paste:
- (IBAction)pinchGestureDidFire:(UIPinchGestureRecognizer *)pinch { UIView *pinchView = pinch.view; CGRect bounds = pinchView.bounds; CGPoint pinchCenter = [pinch locationInView:pinchView]; pinchCenter.x -= CGRectGetMidX(bounds); pinchCenter.y -= CGRectGetMidY(bounds); CGAffineTransform transform = pinchView.transform; transform = CGAffineTransformTranslate(transform, pinchCenter.x, pinchCenter.y); CGFloat scale = pinch.scale; transform = CGAffineTransformScale(transform, scale, scale); transform = CGAffineTransformTranslate(transform, -pinchCenter.x, -pinchCenter.y); pinchView.transform = transform; pinch.scale = 1.0; }