UIView bounds.applying但有旋转

Mak*_*ele 6 uiview cashapelayer ios cgrect swift

我想在视图周围创建一个虚线边框,可以移动/旋转/缩放.

这是我的代码:

func addBorder() {        
    let f = selectedObject.bounds.applying(selectedObject.transform)
    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    borderView.frame = f
    borderView.center = selectedObject.center
    borderView.transform = CGAffineTransform(translationX: selectedObject.transform.tx, y: selectedObject.transform.ty)

    removeBorder() //remove old border

    let f2 = CGRect(x: 0, y: 0, width: borderView.frame.width, height: borderView.frame.height)
    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.frame = f2
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: f2).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}
Run Code Online (Sandbox Code Playgroud)

它看起来像这样: 在此输入图像描述

这还不错,但我希望边框也可以旋转,因为它可能会误导用户,因为触摸区域仅在图像上.

我试图将旋转应用于变换:

func addBorder() {        
    let f = selectedObject.bounds.applying(selectedObject.transform)
    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    borderView.frame = f
    borderView.center = selectedObject.center
    let rotation = atan2(selectedObject.transform.b, selectedObject.transform.a)

    borderView.transform = CGAffineTransform(rotationAngle: rotation).translatedBy(x: selectedObject.transform.tx, y: selectedObject.transform.ty)

    removeBorder() //remove old border

    let f2 = CGRect(x: 0, y: 0, width: borderView.frame.width, height: borderView.frame.height)
    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.frame = f2
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: f2).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}
Run Code Online (Sandbox Code Playgroud)

但旋转后它看起来像这样:

在此输入图像描述

我怎样才能解决这个问题?

Mak*_*ele 0

尽管我已经接受了答案,因为它帮助我理解了我发布最终答案的问题,因为它更重要。我认为这对其他人可能有帮助,因为我在 Stackoverflow 或其他地方找不到这个解决方案。

这个想法是创建一个borderView与 相同的边界selectedObject。这是@Incredible_dev 的解决方案,但是有一个问题:当向borderView任何方向缩放时,线本身会拉伸。我想保持线条尺寸并且只是想在周围selectedObject。因此,我将selectedObject边界与从 中提取的比例相乘selectedObject.transform。然后我从 中复制平移和旋转selectedObject

这是最终的代码:

var borderView: UIView!
var selectedObject: UIView?

extension CGAffineTransform { //helper extension

    func getScale() -> CGFloat {
        return (self.a * self.a + self.c * self.c).squareRoot()
    }

    func getRotation() -> CGFloat {
        return atan2(self.b, self.a)
    }

}

func removeBorder() { //remove the older border
    if borderView != nil {
        borderView.removeFromSuperview()
    }
}

func addBorder() {
    guard let selectedObject = selectedObject else { return }

    removeBorder() //remove old border

    let t = selectedObject.transform
    let s = t.getScale()
    let r = t.getRotation()

    borderView = UIView(frame: CGRect(x: 0, y: 0, width: selectedObject.bounds.width * s, height: selectedObject.bounds.height * s)) //multiply bounds with selectedObject's scale
    dividerImageView.addSubview(borderView) //add borderView to the "scene"

    borderView.transform = CGAffineTransform(translationX: t.tx, y: t.ty).rotated(by: r) //copy translation and rotation, order is important
    borderView.center = selectedObject.center

    let dashedBorder = CAShapeLayer() //create 2-point wide dashed line
    dashedBorder.lineWidth = 2
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: borderView.bounds).cgPath
    borderView.layer.addSublayer(dashedBorder)
}
Run Code Online (Sandbox Code Playgroud)