限制 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
}
您应该分开存储 xScale
和 yScale
,因为一般来说不能保证它们相等。
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
可能不明显,但 a
、b
、c
和 d
属性是 transform
矩阵的元素。您可以在 Quartz 2D Programming Guide. Also you can find math details here 中找到更多详细信息。请注意,b
和 c
元素名称在这两个来源中被交换了。
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
}
您应该分开存储 xScale
和 yScale
,因为一般来说不能保证它们相等。
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
可能不明显,但 a
、b
、c
和 d
属性是 transform
矩阵的元素。您可以在 Quartz 2D Programming Guide. Also you can find math details here 中找到更多详细信息。请注意,b
和 c
元素名称在这两个来源中被交换了。