用平移手势缩放UITextView

时间:2019-07-23 10:06:55

标签: swift rotation uitextview scale cgaffinetransform

我正在创建一个功能,用户可以通过拖动右下角的手势来添加文本标签,缩放和旋转它。

我创建了一个继承自UIView的自定义类,在其上放置了UITextView,在角落的三个视图上分别显示了按钮(关闭,编辑和缩放/旋转),在手势上则显示了透明的UIView。

对不起,我没有足够的声誉来添加图像

文本标签视图结构-https://imgur.com/lDz47fV

我的尝试是在平移手势上使用CGAffineTransform。平移手势位于“旋转按钮视图”上(左下角)

@IBAction func resizeGestureRecognizer(_ sender: UIPanGestureRecognizer) {
        let touchLocation = sender.location(in: self.superview)
        let center = self.center

        switch sender.state {
        case .began:
            self.deltaAngle = CGFloat(atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))) - CGAffineTransformGetAngle(self.transform)
            self.initialDistance = CGPointGetDistance(point1: center, point2: touchLocation)
            //self.initialBounds = self.bounds
        case .changed:
            let angle = atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))
            let angleDiff = Float(self.deltaAngle) - angle
            let scale = CGPointGetDistance(point1: center, point2: touchLocation) / self.initialDistance

            // downscale buttons to ramain same size and rotation
            for button in buttonViews {
                var t = CGAffineTransform.identity
                t = t.rotated(by: CGFloat(angleDiff))
                t = t.scaledBy(x: 1/scale, y: 1/scale)
                button.transform = t
            }

            var t = CGAffineTransform.identity
            t = t.rotated(by: CGFloat(-angleDiff))
            t = t.scaledBy(x: scale, y: scale)
            self.transform = t

//            textView.layer.shouldRasterize = true
//            textView.layer.rasterizationScale = 20
        case .ended, .cancelled:
            print("ended")
        default:
            break
        }
    }

此代码有效,但是每次我尝试调整贴纸大小或旋转贴纸时,它都会缩放回原始比例。我想念什么?

结果-https://imgur.com/QHPlI93

此外,作为缩放字体质量的一种解决方法,我正在使用巨大的fornt大小(100)和0.5的不干胶标签:

override func awakeFromNib() {
        textView.textContainerInset = UIEdgeInsets(top: 10, left: 20, bottom: 10, right: 20)
        frameView.layer.cornerRadius = 13
        showEditingHandlers = true
        textView.becomeFirstResponder()

        let scale: CGFloat = 0.5

        for button in buttonViews {
            var t = CGAffineTransform.identity
            t = t.scaledBy(x: 1/scale, y: 1/scale)
            button.transform = t
        }


        var t = CGAffineTransform.identity
        t = t.scaledBy(x: scale, y: scale)
        self.transform = t

        textView.delegate = self
        update()
    }

1 个答案:

答案 0 :(得分:0)

好吧,如果其他人正在寻找类似的问题,我将发布解决方案

我在班级顶部添加了比例缩放变量:

var scale: CGFloat = 0
var savedScale: CGFloat = 0.5 // 0.5 becuase I use double font size and scaled my sticker by 0.5 to handle font blur

接下来,在手势控制功能中,我只保存了这样的最后一个比例:

@IBAction func resizeGestureRecognizer(_ sender: UIPanGestureRecognizer) {
        let touchLocation = sender.location(in: self.superview)
        let center = self.center



        switch sender.state {
        case .began:

            print("saved scale = \(savedScale)")
            self.deltaAngle = CGFloat(atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))) - CGAffineTransformGetAngle(self.transform)
            self.initialDistance = CGPointGetDistance(point1: center, point2: touchLocation)
        case .changed:
            let angle = atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))
            let angleDiff = Float(self.deltaAngle) - angle
            scale = CGPointGetDistance(point1: center, point2: touchLocation) / self.initialDistance

            print("scale: \(scale)")
            scale = scale * savedScale // <- added this

            // downscale buttons to ramain same size and rotation
            for button in buttonViews {
                var t = CGAffineTransform.identity
                //t = t.rotated(by: CGFloat(angleDiff))
                t = t.scaledBy(x: 1/scale, y: 1/scale)
                button.transform = t
            }

            var t = CGAffineTransform.identity
            t = t.rotated(by: CGFloat(-angleDiff))
            t = t.scaledBy(x: scale, y: scale)
            self.transform = t
        case .ended, .cancelled:
            print("ended")
            savedScale = 1 * scale // <- and this
        default:
            break
        }
    }