Bri*_*any 11 objective-c ios uipinchgesturerecognizer
我已经在我的应用程序中的UIImageView上实现了UIPinchGestureRecognizer,但是无论我在哪里捏图像,它似乎都放大到相同的位置.有谁知道如何让它放大到用户实际"捏"的位置?见下面的代码.
ViewController.m
- (IBAction)scaleImage:(UIPinchGestureRecognizer *)recognizer {
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
recognizer.scale = 1;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
{
BOOL shouldReceiveTouch = YES;
if (gestureRecognizer == tap) {
shouldReceiveTouch = (touch.view == featureImage);
}
return shouldReceiveTouch;
}
Run Code Online (Sandbox Code Playgroud)
rob*_*off 35
缩放变换使原点(0,0)保持不变.因此,要围绕特定点缩放视图,必须首先将该点转换为原点,然后应用缩放,然后转换回来.
- (IBAction)pinchGestureDidFire:(UIPinchGestureRecognizer *)pinch {
Run Code Online (Sandbox Code Playgroud)
首先,我们得到的观点受到挤压.
UIView *pinchView = pinch.view;
Run Code Online (Sandbox Code Playgroud)
要计算夹点的中心,我们需要视图边界的中点,所以我们也得到了界限:
CGRect bounds = pinchView.bounds;
Run Code Online (Sandbox Code Playgroud)
该中心基于捏的触摸的质心,我们得到这样的方式:
CGPoint pinchCenter = [pinch locationInView:pinchView];
Run Code Online (Sandbox Code Playgroud)
但实际上我们需要相对于视图中心的夹点偏移,因为默认情况下视图的变换相对于视图的中心.(您可以通过更改视图来更改此设置layer.anchorPoint.)
pinchCenter.x -= CGRectGetMidX(bounds);
pinchCenter.y -= CGRectGetMidY(bounds);
Run Code Online (Sandbox Code Playgroud)
现在我们可以更新视图的转换.首先,我们获得当前的变换:
CGAffineTransform transform = pinchView.transform;
Run Code Online (Sandbox Code Playgroud)
然后我们更新它以将夹点中心转换为原点:
transform = CGAffineTransformTranslate(transform, pinchCenter.x, pinchCenter.y);
Run Code Online (Sandbox Code Playgroud)
现在我们可以应用比例:
CGFloat scale = pinch.scale;
transform = CGAffineTransformScale(transform, scale, scale);
Run Code Online (Sandbox Code Playgroud)
然后我们将视图翻译回来:
transform = CGAffineTransformTranslate(transform, -pinchCenter.x, -pinchCenter.y);
Run Code Online (Sandbox Code Playgroud)
现在我们可以使用修改后的转换更新视图:
pinchView.transform = transform;
Run Code Online (Sandbox Code Playgroud)
最后,我们重置了手势识别器的比例,因为我们已应用当前比例:
pinch.scale = 1.0;
}
Run Code Online (Sandbox Code Playgroud)
演示:

请注意,在模拟器中,您可以按住选项(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;
}
Run Code Online (Sandbox Code Playgroud)
Bru*_*ino 13
迅速实施抢劫答案:
@objc private func pinchHandler(gesture: UIPinchGestureRecognizer) {
if let view = gesture.view {
switch gesture.state {
case .changed:
let pinchCenter = CGPoint(x: gesture.location(in: view).x - view.bounds.midX,
y: gesture.location(in: view).y - view.bounds.midY)
let transform = view.transform.translatedBy(x: pinchCenter.x, y: pinchCenter.y)
.scaledBy(x: gesture.scale, y: gesture.scale)
.translatedBy(x: -pinchCenter.x, y: -pinchCenter.y)
view.transform = transform
gesture.scale = 1
case .ended:
// Nice animation to scale down when releasing the pinch.
// OPTIONAL
UIView.animate(withDuration: 0.2, animations: {
view.transform = CGAffineTransform.identity
})
default:
return
}
}
}
Run Code Online (Sandbox Code Playgroud)