Comment reconnaître quelle image a été touchée

Je suis en train de développer une application dans laquelle l'user pourra glisser et déposer des objects sur une canvas et quand il relâchera l'image, il sera dessiné sur la canvas.

C'est ma class DragImage qui gère les touches:

class DragImages: UIImageView { var originalPos : CGPoint! var dropTarget: UIView? override init (frame : CGRect){ super.init(frame: frame) } required 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 } } 

Dans ma class ViewController j'ai ajouté ce morceau de code pour gérer les touches 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){ } 

J'ai réussi à get la position X et Y quand l'image est traînée sur la canvas mais je ne peux pas find un moyen de reconnaître laquelle des 4 images est abandonnée afin que je dessine celle-là spécifique!

Vous pouvez append l'expéditeur à votre notification (et également la position):

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

et l'get plus tard dans itemDroppedOnTree :

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

Je recommand cependant contre cela et plaide pour utiliser un delegate pour informer le ViewController place. (Basé sur l'opinion: En général, utilisez les notifications pour un nombre d'émissions limité.)

La fonction de délégué doit avoir l'expéditeur comme premier paramètre. Selon func tableView: tableView:UITableView, cellForRowAt indexPath:IndexPath) .

De cette façon, vous savez quelle image envoie sa nouvelle position et pouvez la comparer à votre propriété comme dans l'exemple ci-dessus:

  if dragImage === dragImage1 {... 

Votre code et délégué de travail pour coller à 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 } required 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 

Résultat: