'Clicking a SKSprite Node in swift

I am really really frustrated by this and I have been trying to get it to work for almost two full days now :(

How do I go about adding a click event to a SKSpriteNode in swift

  let InstantReplay:SKSpriteNode = SKSpriteNode(imageNamed: "InstantReplay")
  InstantReplay.position = CGPoint(x: size.width + InstantReplay.size.width/2, y: size.height/2)
  InstantReplay.size = CGSize(width: size.width/1.4, height: size.height/8)
  addChild(InstantReplay)

  InstantReplay.runAction(SKAction.moveToX(size.width/2, duration: NSTimeInterval(1)))

All I want to happen is when "InstantReplay" is clicked for it to run a function called "InstantReplay_Clicked", How would I go about Implementing this?

Any help much appreciated :)



Solution 1:[1]

Give your SKSpriteNode a name so we can identify it in the touchesBegan or touchesEnded method of your SKScene.

Also set userInteractionEnabled of your SKSpriteNode to false, so that it doesn't trap touch events for itself, and not pass them up to the your Scene.

override init() {
    super.init()

    let instantReplay = SKSpriteNode(imageNamed: "InstantReplay")
    instantReplay.position = CGPoint(x: size.width + instantReplay.size.width/2, y: size.height/2)
    instantReplay.size = CGSize(width: size.width/1.4, height: size.height/8)
    instantReplay.name = "InstantReplay"; // set the name for your sprite
    instantReplay.userInteractionEnabled = false; // userInteractionEnabled should be disabled
    self.addChild(instantReplay)
}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    let location = touches.anyObject()?.locationInNode(self)
    let node = self.nodeAtPoint(location!)
    if (node.name == "InstantReplay") {
        println("you hit me with your best shot!")
    }
}

(oh - i also renamed your instantReplay variable to use lowerCamelCase, in line with Swift best practices.

Solution 2:[2]

Swift 4 Update

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  for t in touches {
    let node = self.atPoint(t.location(in :self))
    if (node.name == "InstantReplay") {
        print("you hit me with your best shot!")
    }
  }
  
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Craig Grummitt
Solution 2 Willeke