ios - 捏合/缩放图像,以触摸为中心

时间:2013-04-19 19:28:18

标签: ios uigesturerecognizer cgaffinetransform uipangesturerecognizer uipinchgesturerecognizer

我可以像这样使用捏合/缩放功能:

- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{

    if([recognizer state] == UIGestureRecognizerStateBegan) {
        _lastScale = 1.0;
    }

    CGFloat scale = 1.0 - (_lastScale - [recognizer scale]);

    CGAffineTransform currentTransform = self.imageForEditing.transform;
    CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);

    [self.imageForEditing setTransform:newTransform];

    _lastScale = [recognizer scale];


}

问题是图像会根据图像的中心进行缩放,因此如果您首先平移图像使其不居中,然后进行捏合/缩放,则不会缩放图像之间的区域。我认为这必须是一个已经解决和解决的常见问题,但我无法找到解决方案。

3 个答案:

答案 0 :(得分:1)

您可以将图层的锚点设置为两个捏合触点的“中心”:

- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer
{

    if([recognizer state] == UIGestureRecognizerStateBegan) {
        _lastScale = 1.0;
        if ([recognizer numberOfTouches] >= 2) { //should always be true when using a PinchGR
            CGPoint touch1 = [recognizer locationOfTouch:0 inView:self.imageForEditing];
            CGPoint touch2 = [recognizer locationOfTouch:1 inView:self.imageForEditing];
            CGPoint mid;
            mid.x = ((touch2.x - touch1.x) / 2) + touch1.x;
            mid.y = ((touch2.y - touch1.y) / 2) + touch1.y;
            CGSize imageViewSize = self.imageForEditing.frame.size;
            CGPoint anchor;
            anchor.x = mid.x / imageViewSize.width;
            anchor.y = mid.y / imageViewSize.height;
            self.imageForEditing.layer.anchorPoint = anchor;
        }
    }

    CGFloat scale = 1.0 - (_lastScale - [recognizer scale]);

    CGAffineTransform currentTransform = self.imageForEditing.transform;
    CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);

    [self.imageForEditing setTransform:newTransform];

    _lastScale = [recognizer scale];


}

这样,图像应相对于两个触摸之间的中心缩放。

有关详细信息,请参阅Core Animation Programming Guide - Core Animation Basics

答案 1 :(得分:1)

@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
        }


    }
}

答案 2 :(得分:0)

尝试下面的代码来放大/缩小并使用Pinch Gesture Recognizer翻译视图的中心。 将这段代码放在UIGestureRecognizerStateBegan:

        previousTouchPoint = [pinchRecognizer locationInView:self.view];

,这在您的UIGestureRecognizerStateChanged:

       //zoom in/out view based on scale
        CGFloat zoomScale = pinchRecognizer.scale;
        CGRect tRect = pinchedView.bounds;
        tRect.size.width = pinchedView.frame.size.width * zoomScale;
        tRect.size.height = pinchedView.frame.size.height * zoomScale;
        pinchedView.bounds = tRect;

        //sets the center of view
        CGPoint currentTouchPoint = [pinchRecognizer locationInView:self.view];
        CGPoint tCenter = pinchedView.center;
        tCenter.x -= (previousTouchPoint.x - currentTouchPoint.x);
        tCenter.y -= (previousTouchPoint.y - currentTouchPoint.y);
        pinchedView.center = tCenter;
        previousTouchPoint = [pinchRecognizer locationInView:self.view];