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