限制UIPinchGestureRecognizer缩放级别目标C到Swift 3.0

时间:2017-02-16 09:29:20

标签: ios swift core-image catransform3d catransformlayer

iOS 10.2 Swift 3.0

尝试从Paul Solt博客翻译这段代码。修正了SO海报,更新了代码!

http://paulsolt.com/blog/2011/03/limiting-uipinchgesturerecognizer-zoom-levels

示例代码

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)gestureRecognizer {

if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}

if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {

CGFloat currentScale = [[[gestureRecognizer view].layer     valueForKeyPath:@"transform.scale"] floatValue];

// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 1.0;

CGFloat newScale = 1 -  (lastScale - [gestureRecognizer scale]); // new     scale is in the range (0-1)
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;

lastScale = [gestureRecognizer scale];  // Store the previous scale factor     for the next pinch gesture call
}
}

差不多完成了,但似乎找不到对这里用于Swift 3.0的CATransform密钥的引用。我的代码......

if sender.state == .began {
        // Reset the last scale, necessary if there are multiple objects with different scales
        lastScale = sender.scale
    }

    if sender.state == .began || sender.state == .changed {

        // UPDATED
        currentScaleX = self.image2P.transform.scaleX
        currentScaleY = self.image2P.transform.scaleY


        self.image2P.transform = self.image2P.transform.scaledBy(x: 1.1, y: 1.1)


        // Constants to adjust the max/min values of zoom
        let kMaxScale:CGFloat = 2.0;
        let kMinScale:CGFloat = 1.0;

        var newScale = 1 -  (lastScale - sender.scale) // new scale is in the range (0-1)
        newScale = min(newScale, kMaxScale / currentScaleX)
        newScale = max(newScale, kMinScale / currentScaleY)
        self.image2P.transform = self.image2P.transform.scaledBy(x: newScale, y: newScale)

        lastScale = sender.scale  // Store the previous scale factor for the next pinch gesture call
    }

1 个答案:

答案 0 :(得分:1)

您应该分别存储xScaleyScale,因为一般来说不能保证它们是平等的。

extension CGAffineTransform {
    var scaleX: CGFloat {
        return (a > 0 ? 1 : -1) * sqrt (a*a + c*c)
    }

    var scaleY: CGFloat {
        return (d > 0 ? 1 : -1) * sqrt (b*b + d*d)
    }
}

即使您的观看次数已旋转和/或已翻译,这些扩展方法也会返回正确的比例因子:

view.transform = CGAffineTransform(scaleX: 1.5, y: 1.2).rotated(by: .pi/3.0).translatedBy(x: 50, y: 30)
print("scaleX = \(view.transform.scaleX), scaleY = \(view.transform.scaleY)")

输出:

  

scaleX = 1.5,scaleY = 1.2

可能并不明显,但abcd属性是transform矩阵的元素。您可以在Quartz 2D Programming Guide中找到更多详细信息。您还可以找到数学详细信息here。请注意,bc元素名称在这两个来源中互换。