Home > Back-end >  How can I select a specific circle?
How can I select a specific circle?

Time:05-11

I have created Circle using "draw" and can place it anywhere on view. but when I want to move a specific circle by clicking it. it selects "LAST" created circle. how can I select a specific circle? please guide me for the same. if anything else you need let me know.

**CircleView**
import UIKit

class CircleView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .clear
    }


    required init(coder aDecoder : NSCoder) {
        fatalError("init(coder : ) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext(){

            context.setLineWidth(2)
            UIColor.yellow.set()


            let circleCenter = CGPoint(x: frame.size.width / 2, y: frame.self.height / 2)
            let circleRadius = (frame.size.width - 10) / 2

            context.addArc(center: circleCenter, radius: circleRadius, startAngle: 0, endAngle: .pi * 2, clockwise: true)

            context.strokePath()
        }
    }


}

**ViewController**
import UIKit

class ViewController: UIViewController {


    var circleView = CircleView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    let circleWidth = CGFloat(100)
    var lastCircleCenter = CGPoint()
    var currentCenter = CGPoint()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.lightGray
        circleView.isUserInteractionEnabled = true
    }


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first{
            lastCircleCenter  = touch.location(in: view)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first{
            let circleCenter = touch.location(in: view)

            if circleCenter == lastCircleCenter{

            let circleHeight = circleWidth

            circleView = CircleView(frame: CGRect(x: circleCenter.x - circleWidth / 2, y: circleCenter.y - circleWidth / 2, width: 100, height: 100))

                view.addSubview(circleView)
            }
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        guard let touch = touches.first else {
            return
        }
        let location = touch.location(in: view)
        circleView.center = location
    }

}

how can I select a specific circle? please guide me for the same. if anything else you need let me know. how can I select a specific circle? please guide me for the same. if anything else you need let me know.

CodePudding user response:

If you are creating multiple circles and adding them to your view, I would suggest to keep track of the created circles in a collection. That way on each touch you can check if the coordinate matches any of the created circles. Based on that you can determine if to create a new circle or to move an existing one.

Example:

class ViewController: UIViewController {
    var circleViews: [CircleView] = []
    let circleWidth = CGFloat(100)
    var draggedCircle: CircleView?

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // Do nothing if a circle is being dragged
        // or if we do not have a coordinate
        guard draggedCircle == nil, let point = touches.first?.location(in: view) else {
            return
        }

        // Do not create new circle if touch is in an existing circle
        // Keep the reference of the (potentially) dragged circle
        if let draggedCircle = circleViews.filter({ UIBezierPath(ovalIn: $0.frame).contains(point) }).first {
            self.draggedCircle = draggedCircle
            return
        }

        // Create new circle and store in an array
        let offset = circleWidth / 2
        let rect = CGRect(x: point.x - offset, y: point.y - offset, width: circleWidth, height: circleWidth)
        let circleView = CircleView(frame: rect)
        circleViews.append(circleView)
        view.addSubview(circleView)
        // The newly created view can be immediately dragged
        draggedCircle = circleView
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        // If touches end then a circle is never dragged
        draggedCircle = nil
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let draggedCircle = draggedCircle, let point = touches.first?.location(in: view) else {
            return
        }

        draggedCircle.center = point
    }
}
  • Related