Cómo reconocer qué image fue tocada

Estoy desarrollando una aplicación que el usuario podrá drag and drop elementos en un canvas y cuando suelta la image se dibuja en el canvas.

Esta es mi class de DragImage que maneja los toques:

class DragImages: UIImageView { var originalPos : CGPoint! var dropTarget: UIView? override init (frame : CGRect){ super.init(frame: frame) } requinetworking init?(coder aDecoder : NSCoder){ super.init(coder : aDecoder) } override func touchesBegan(_ touches : Set<UITouch>,with event: UIEvent?){ originalPos = self.center } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first{ let position = touch.location(in: self.superview) self.center = CGPoint(x : position.x, y : position.y) } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first, let target = dropTarget{ let position = touch.location(in: self.superview) if target.frame.contains(position){ NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "onTargetDropped"), object: nil)) }else { self.center = originalPos } } print(self.center.x, self.center.y) self.center = originalPos } func getEndPosX() -> CGFloat{ return self.center.x } func getEndPosY() -> CGFloat { return self.center.y } } 

En mi class ViewController agregué esta pieza de código para manejar los toques, etc:

  ornament1.dropTarget = xmasTree ornament2.dropTarget = xmasTree ornament3.dropTarget = xmasTree ornament4.dropTarget = xmasTree NotificationCenter.default.addObserver(self, selector: #selector(ViewController.itemDroppedOnTree(_:)), name: NSNotification.Name(rawValue: "onTargetDropped"), object: nil) } func itemDroppedOnTree(_ notif : AnyObject){ } 

Logré get la position X e Y cuando la image se arrastra sobre el canvas, ¡pero no puedo encontrar una forma de reconocer cuál de las 4 imágenes se está cayendo para que pueda dibujar esa específica!

Puede agregar el remitente a su notificación (y también a la position):

 NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "onTargetDropped"), object: self, userInfo: ["position":position])) 

y getlo más adelante en itemDroppedOnTree :

 func itemDroppedOnTree(_ notif : NSNotification){ let position = notif.userInfo["position"] let sender = notif.object as! DragImage if sender === dragImage1 { //... } else if sender === dragImage2 { //... } } 

Sin embargo, recomiendo que no lo haga y suplico usar un delegate para informar al ViewController . (Basada en la opinión: en general, use Notificaciones para muchas transmisiones solamente).

La function de delegado debe tener al remitente como primer parámetro. De acuerdo con func tableView: tableView:UITableView, cellForRowAt indexPath:IndexPath) .

De esta forma, usted sabe qué image está enviando su nueva position y puede compararlo con su propiedad como en el ejemplo anterior:

  if dragImage === dragImage1 {... 

Su código más delegado de trabajo para pegar en Playground:

 import UIKit import PlaygroundSupport protocol DragImageDelegate: class { func dragimage(_ dragImage:DragImage, didDropAt position:CGPoint) } class DragImage: UIImageView { weak var delegate: DragImageDelegate? var originalPos : CGPoint! var dropTarget: UIView? override init (frame : CGRect) { super.init(frame: frame) isUserInteractionEnabled = true } requinetworking init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func touchesBegan(_ touches : Set<UITouch>,with event: UIEvent?){ originalPos = self.center } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first{ let position = touch.location(in: self.superview) self.center = CGPoint(x : position.x, y : position.y) } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first, let target = dropTarget { let position = touch.location(in: self.superview) if target.frame.contains(position){ print(self.center.x, self.center.y) guard let delegate = self.delegate else { print("delegate not set") return } print(self.center.x, self.center.y) delegate.dragimage(self, didDropAt: position) return } } self.center = originalPos } } class MyVC: UIViewController, DragImageDelegate { let dragImage1 = DragImage(frame: CGRect(x: 0.0, y: 0.0, width: 30.0, height: 30.0)) let dragImage2 = DragImage(frame: CGRect(x: 0.0, y: 100.0, width: 30.0, height: 30.0)) override func viewDidLoad() { let target = UIView(frame: CGRect(x: 200.0, y: 400.0, width: 30.0, height: 30.0)) target.backgroundColor = .black view.addSubview(target) dragImage1.backgroundColor = .white dragImage2.backgroundColor = .white dragImage1.dropTarget = target dragImage2.dropTarget = target view.addSubview(dragImage1) view.addSubview(dragImage2) dragImage1.delegate = self dragImage2.delegate = self } private func move(_ view:UIView, to position:CGPoint) { view.frame = CGRect(x: position.x, y: position.y, width: view.frame.size.width, height: view.frame.size.height) } // MARK: - DragImageDelegate func dragimage(_ dragImage: DragImage, didDropAt position: CGPoint) { if dragImage === dragImage1 { move(dragImage1, to: position) } else if dragImage === dragImage2 { move(dragImage2, to: position) } } } var container = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 300.0, height: 600.0)) let myVc = MyVC() myVc.view.frame = CGRect(x: 0.0, y: 0.0, width: 300.0, height: 600.0) myVc.view.backgroundColor = .green container.addSubview(myVc.view) PlaygroundPage.current.liveView = container 

Resultado: