Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView bounds.applying but with rotation

I'd like to create a dash border around a view, which can be moved/rotated/scaled.

Here's my code:

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

And it looks like this: enter image description here

It's not bad, but I want the border to be rotated as well, because it may be misleading for the user as touch area is only on the image.

I've tried to apply rotation to the transform:

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

But after rotating it looks like this:

enter image description here

How can I fix this?

like image 527
Makalele Avatar asked Oct 01 '18 10:10

Makalele


2 Answers

Here is a sample based on your code that should do:

//initial transforms
selectedObject.transform = CGAffineTransform.init(rotationAngle: .pi / 4).translatedBy(x: 150, y: 15)

func addBorder() {
    let borderView = UIView.init(frame: selectedObject.bounds)
    self.view.addSubview(borderView)
    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    borderView.center = selectedObject.center
    borderView.transform = selectedObject.transform

    removeBorder() //remove old border

    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(rect: borderView.bounds).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}
like image 167
Aris Avatar answered Oct 19 '22 04:10

Aris


Here is the solution of for problem:

func addBorder() {

    borderView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5) //just for testing
    let degrees: CGFloat = 20.0 //the value in degrees for rotation
    let radians: CGFloat = degrees * (.pi / 180)
    borderView.transform = CGAffineTransform(rotationAngle: radians)

    removeBorder()

    let dashedBorder = CAShapeLayer()
    dashedBorder.strokeColor = UIColor.black.cgColor
    dashedBorder.lineDashPattern = [2, 2]
    dashedBorder.frame = borderView.bounds
    dashedBorder.fillColor = nil
    dashedBorder.path = UIBezierPath(roundedRect: borderView.bounds, cornerRadius:0).cgPath
    dashedBorder.name = "border"
    borderView.layer.addSublayer(dashedBorder)
}

The above code is tested in Xcode 10 with Swift 4.2

like image 23
Incredible_Dev Avatar answered Oct 19 '22 05:10

Incredible_Dev