ios UIPinchGestureRecognizer 将捏合视图定位在两个手指之间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4947148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:50:11  来源:igfitidea点击:

UIPinchGestureRecognizer position the pinched view between the two fingers

ipadiosmulti-touch

提问by Thomas Joulin

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.

我成功地实现了缩放视图。但是,该视图并没有将自己定位在我希望的位置。对于带有 iPad 的 stackoverflowers,我希望我的视图像 iPad Photos.app 一样居中:当你在相册上捏合和缩放时,照片会在一个正在扩展的视图中显示出来。该视图大约以第一根手指的右上角和另一根手指的左下角手指为中心。我将它与平移识别器混合在一起,但这样用户总是必须捏住,然后平移才能调整。

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...)

这是如此生动的解释,如果不清楚,我可以发布我的应用程序的视频(不是秘密,我正在尝试重现 iPad 的 Photos.app ......)

So for an initial position of the fingers, begining zooming :

所以对于手指的初始位置,开始缩放:

enter image description here

在此处输入图片说明

This is the actual "zoomed" frame for now. The square is bigger, but the position is below the fingers

这是目前实际的“缩放”框架。正方形比较大,但是位置在手指下面

given the start position

给定起始位置

Here is what I would like to have : same size, but different origin.x and y :

这是我想要的:相同的大小,但不同的 origin.x 和 y :

enter image description here

在此处输入图片说明

(sorry about my poor photoshop skills ^^)

(抱歉我糟糕的Photoshop技能^^)

回答by mishimay

You can get the CGPointof the midpoint between two fingers via the following code in the method handlingPinchGesture.

您可以CGPoint通过方法中的以下代码获取两根手指之间的中点handlingPinchGesture

CGPoint point = [sender locationInView:self];

My whole handlePinchGesturemethod is below.

我的整个handlePinchGesture方法如下。

/*
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];
}

回答by Felix

Have a look at the Touches sample project. Specifically these methods could help you:

查看Touches 示例项目。具体来说,这些方法可以帮助您:

// 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];
    }
}