ios - iOS Swift:在不调整大小的情况下旋转和缩放 UIView
问题描述
我有一个 UIView,我想通过平移和捏合手势进行缩放和旋转。但问题是当我缩放视图时,然后当我旋转它时,它会在缩放之前调整回初始值。
extension UIView {
func addPinchGesture() {
var pinchGesture = UIPinchGestureRecognizer()
pinchGesture = UIPinchGestureRecognizer(target: self,
action: #selector(handlePinchGesture(_:)))
self.addGestureRecognizer(pinchGesture)
}
@objc func handlePinchGesture(_ sender: UIPinchGestureRecognizer) {
self.transform = self.transform.scaledBy(x: sender.scale, y: sender.scale)
sender.scale = 1
}
}
// ROTATION
extension UIView {
func addRotationGesture() {
var rotationGesture = RotationGestureRecognizer()
rotationGesture = RotationGestureRecognizer(target: self,
action: #selector(handleRotationGesture(_:)))
self.addGestureRecognizer(rotationGesture)
}
@objc func handleRotationGesture(_ sender: RotationGestureRecognizer) {
var originalRotation = CGFloat()
switch sender.state {
case .began:
sender.rotation = sender.lastRotation
originalRotation = sender.rotation
case .changed:
let newRotation = sender.rotation + originalRotation
self.transform = CGAffineTransform(rotationAngle: newRotation) // Rotation is fine but it is resizing view
// self.transform = self.transform.rotated(by: newRotation / CGFloat(180 * Double.pi)) // NOT WORKING i.e. irregular rotation
case .ended:
sender.lastRotation = sender.rotation
default:
break
}
}
}
缩放前
缩放后
旋转后
我希望它在不影响视图大小的情况下旋转。我怎样才能做到这一点?
解决方案
应用旋转变换时,您正在重置视图的比例变换。创建一个属性以保持视图的原始比例。
var currentScale: CGFloat = 0
捏合完成后,将 currentScale 值存储到当前比例。然后在旋转时也使用这个比例,然后再应用旋转。
let scaleTransform = CGAffineTransform(scaleX: currentScale, y: currentScale)
let concatenatedTransform = scaleTransform.rotated(by: newRotation)
self.transform = concatenatedTransform
您正在使用扩展来添加手势识别器,因此您无法存储 currentScale。您还可以从当前变换值中获取视图的比例值。这是您的代码的样子,
extension UIView {
var currentScale: CGPoint {
let a = transform.a
let b = transform.b
let c = transform.c
let d = transform.d
let sx = sqrt(a * a + b * b)
let sy = sqrt(c * c + d * d)
return CGPoint(x: sx, y: sy)
}
func addPinchGesture() {
var pinchGesture = UIPinchGestureRecognizer()
pinchGesture = UIPinchGestureRecognizer(target: self,
action: #selector(handlePinchGesture(_:)))
self.addGestureRecognizer(pinchGesture)
}
@objc func handlePinchGesture(_ sender: UIPinchGestureRecognizer) {
self.transform = self.transform.scaledBy(x: sender.scale, y: sender.scale)
sender.scale = 1
}
}
// ROTATION
extension UIView {
func addRotationGesture() {
var rotationGesture = RotationGestureRecognizer()
rotationGesture = RotationGestureRecognizer(target: self,
action: #selector(handleRotationGesture(_:)))
self.addGestureRecognizer(rotationGesture)
}
@objc func handleRotationGesture(_ sender: RotationGestureRecognizer) {
var originalRotation = CGFloat()
switch sender.state {
case .began:
sender.rotation = sender.lastRotation
originalRotation = sender.rotation
case .changed:
let scale = CGAffineTransform(scaleX: currentScale.x, y: currentScale.y)
let newRotation = sender.rotation + originalRotation
self.transform = scale.rotated(by: newRotation)
case .ended:
sender.lastRotation = sender.rotation
default:
break
}
}
}
我将此答案用作提取比例值的参考。
推荐阅读
- c# - 您如何从 Dictionary 值之一中找到所需的日期?
- python-3.x - Graphviz 左对齐边缘标签文本
- angular - 计算 ts / angular 中字符串变量的小时差
- go - 如何使用 bash 的括号扩展语法创建目录树
- database - prisma 模式中的一对多自关系
- javascript - 如何从 Firebase 中的 batch.commit() 计划函数返回一个承诺
- javascript - Javascript - 加载时选择元素
- python - 为什么我收到一个错误,显示模块“多处理”没有属性“sharedctypes”?
- express - 异步等待句柄 Promise {
} 快递API - bash - 如何在 bash 脚本中多次使用带有“-”(破折号)的标准输入?