【问题标题】:UIPinchGestureRecognizer position the pinched view between the two fingersUIPinchGestureRecognizer 定位两个手指之间的捏合视图
【发布时间】:2011-06-24 05:54:23
【问题描述】:

我成功实现了视图的缩放。但是,视图并没有将自己定位在我希望的位置。对于带有 iPad 的 stackoverflowers,我希望我的视图像 iPad Photos.app 一样居中:当您在相册上捏合和缩放时,照片会以不断扩大的视图呈现。该视图大致居中,第一根手指的右上角和另一根手指的左下角。我将它与平移识别器混合使用,但这样用户总是需要捏合,然后平移才能进行调整。

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

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

这是目前实际的“缩放”帧。正方形更大,但位置在手指下方

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

(抱歉我的photoshop技术不好^^)

【问题讨论】:

  • 嗨,Thomas,我对此也很感兴趣。您找到任何解决方案了吗?你有任何示例代码吗?谢谢~
  • 我没有时间回到这个问题上,但@md_develop 的答案看起来很棒。如果可行,我会尝试找时间更新我的代码并接受答案

标签: ipad ios multi-touch


【解决方案1】:

看看Touches sample project。具体来说,这些方法可以帮助您:

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

【讨论】:

  • 谢谢,但是使用view.transform 也可以调整我的子视图的大小...有没有办法防止这种情况发生?
  • #import - 我需要这个作为锚点
【解决方案2】:

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

CGPoint point = [sender locationInView:self];

我的整个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];
}

【讨论】:

  • 当 [sender locationInView:self] 总是返回同一个点,即两个捏合手指之间的中点时,这怎么可能?
  • @Guy 中点在UIGestureRecognizerStateBegan 之后发生变化,因为您将手指移开或移近。 locationInView:self 返回两个手指之间的质心。那部分确实有效。虽然 1 小时后我仍然无法让它在我的应用程序中工作,我有一堆需要移动的层..
  • 我用了这个方法,视图翻译正确。然而,它的翻译方式并不像照片应用那样流畅
  • @mishimay 如果我添加一个名为 _myLayer 的子层,并将代码中的 self.layer 替换为 _myLayer,您的代码将无法正常工作。为什么以及如何解决它?提前致谢。
猜你喜欢
  • 2012-12-08
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多