缩放变换不会改变原点(0,0)。因此,如果要将视图围绕特定点进行缩放,必须先将该点平移到原点,然后应用缩放,最后再平移回来。
- (IBAction)pinchGestureDidFire:(UIPinchGestureRecognizer *)pinch {
首先,我们得到被捏住的视图。
UIView *pinchView = pinch.view
为了计算捏合点的中心位置,我们需要获取视图边界的中点,因此我们也要获取边界:
要计算捏合点的中心位置,我们需要获得视图边界的中点,因此我们还要获取边界:
CGRect bounds = pinchView.bounds;
中心点基于捏合触点的重心,我们通过以下方式获得:
CGPoint pinchCenter = [pinch locationInView:pinchView]
但实际上我们需要相对于视图中心的捏合偏移量,因为视图的变换默认是相对于视图中心的。 (您可以通过更改视图的layer.anchorPoint
来更改此设置。)
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;
}
演示:
![收缩比例](https://istack.dev59.com/v7Va3.gif)
请注意,在模拟器中,您可以按住选项(alt)进行收缩手势。同时按住Shift键(同时按下选项键),可以将两个触摸点移动到一起。
以下是全部代码,可供复制粘贴使用:
- (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;
}
NSLog
或断点以确保它被调用了? - rob mayoffUIPinchGestureRecognizer
直接实现是不可能的,因为该识别器仅报告单个“scale”因子。您需要查看手势中的各个触摸点,在每次更新时跟踪它们的移动,并自己计算各个X和Y比例因子。 - rob mayoff