MadNeuro
MadNeuro

Reputation: 33

How to create a connecting line between drag-able UIViews in Swift 3? and measure the line angle

I need to have two views in screen for dragging (done whit UIPanGestureRecogniser) and a connecting line between , so when I move the views freely the line stay attached (like a rope between the views). and measure the angle of this line. this is my code so far

    var rect1:UIView!
    var rect2:UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // create my two views

        rect1 = UIView(frame: CGRect(x: 50, y: 150, width: 40, height: 40))
        rect1.backgroundColor = UIColor.orange
        self.view.addSubview(rect1)

        rect2 = UIView(frame: CGRect(x: 200, y: 150, width: 40, height: 40))
        rect2.backgroundColor = UIColor.yellow
        self.view.addSubview(rect2)

        // and the UIPanGestureRecognizer objects

        let gesture1 = UIPanGestureRecognizer(target: self, action: #selector(dragView))
        rect1.addGestureRecognizer(gesture1)

        let gesture2 = UIPanGestureRecognizer(target: self, action: #selector(dragView))
        rect2.addGestureRecognizer(gesture2)

        // add mi connecting line between 

    func addLine(fromPoint start: rect1.center, toPoint end:rect2.center) 
        }

    // create the func for moving the views

    func dragView(_ sender: UIPanGestureRecognizer)
    {        
        let point = sender.location(in: self.view)    
        let theDraggedView = sender.view!
        theDraggedView.center = point        
    }     
    // and the func for line creation    


     func addLine(fromPoint start: CGPoint, toPoint end:CGPoint) 
    {
    let line = CAShapeLayer()
    let linePath = UIBezierPath()
    linePath.move(to: start)
    linePath.addLine(to: end)
    line.path = linePath.cgPath
    line.strokeColor = UIColor.red.cgColor
    line.lineWidth = 2
    line.lineJoin = kCALineJoinRound
    self.view.layer.addSublayer(line)
    }
}

and here I am stock!! if I use the addline func again inside the dragView, creates hundreds of lines. and don't know what to do next

Upvotes: 2

Views: 678

Answers (1)

Dharmesh Kheni
Dharmesh Kheni

Reputation: 71854

Thats because you are not removing previous line when you call addLine function again and again.

For remove previous line declare var line = CAShapeLayer() at the top into the class so you can get previous line you have drawn and then whenever you call addLine function just remove previous line from superview at start like:

line.removeFromSuperlayer()

And your complete code will be:

import UIKit

class ViewController: UIViewController {

    var rect1:UIView!
    var rect2:UIView!
    var line = CAShapeLayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        rect1 = UIView(frame: CGRect(x: 50, y: 150, width: 40, height: 40))
        rect1.backgroundColor = UIColor.orange
        self.view.addSubview(rect1)

        rect2 = UIView(frame: CGRect(x: 200, y: 150, width: 40, height: 40))
        rect2.backgroundColor = UIColor.yellow
        self.view.addSubview(rect2)

        // and the UIPanGestureRecognizer objects

        let gesture1 = UIPanGestureRecognizer(target: self, action: #selector(dragView))
        rect1.addGestureRecognizer(gesture1)

        let gesture2 = UIPanGestureRecognizer(target: self, action: #selector(dragView))
        rect2.addGestureRecognizer(gesture2)

        addLine(start: rect1.center, toPoint:rect2.center)
    }

    func dragView(_ sender: UIPanGestureRecognizer) {

        let point = sender.location(in: self.view)
        let theDraggedView = sender.view!
        theDraggedView.center = point
        addLine(start: rect1.center, toPoint:rect2.center)
    }


    func addLine(start: CGPoint, toPoint end:CGPoint) {

        line.removeFromSuperlayer()
        let linePath = UIBezierPath()
        linePath.move(to: start)
        linePath.addLine(to: end)
        line.path = linePath.cgPath
        line.strokeColor = UIColor.red.cgColor
        line.lineWidth = 2
        line.lineJoin = kCALineJoinRound
        self.view.layer.addSublayer(line)
    }
}

And your result will be: enter image description here

Upvotes: 1

Related Questions