限制 UIPinchGestureRecognizer 缩放级别 Objective C 到 Swift 3.0

Limiting UIPinchGestureRecognizer Zoom Levels Objective C to Swift 3.0

iOS10.2Swift3.0

正在尝试翻译 Paul Solt 博客中的这段代码。由 SO poster 修复,更新代码!

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
    }

您应该分开存储 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)
    }
}

即使您的视图也是 rotated and/or translated[=33=,这些扩展方法也会 return 正确的比例因子]:

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. Also you can find math details here 中找到更多详细信息。请注意,bc 元素名称在这两个来源中被交换了。