iOS Swift:无需调整大小即可旋转和缩放UIView

时间:2019-01-04 15:21:26

标签: ios swift uiview cgaffinetransform

我有一个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
        }
    }

}

缩放之前

enter image description here

缩放后

enter image description here

旋转后

enter image description here

我希望它可以旋转而不影响视图大小。我该如何实现?

2 个答案:

答案 0 :(得分:1)

您正在应用旋转变换时重置视图的比例变换。创建一个属性以保留视图的原始比例。

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

我用这个answer作为提取比例值的参考。

答案 1 :(得分:0)

我面临着同样的问题一旦用手指捏住,然后从按钮旋转后,它会自动从当前比例缩小,但我在下面设置了逻辑。

1111