15

How do I programmatically add a button that will run an action when it's clicked? What code would be used?

I am used to just adding a button in the storyboard and running an IBAction from there.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Skiddyflyer
  • 213
  • 1
  • 2
  • 8

5 Answers5

31

Adding a button in SpriteKit and responding to taps on it is not quite as easy as it is in UIKit. You basically need to create an SKNode of some sort which will draw your button and then check to see if touches registered in your scene are within that node's bounds.

A really simple scene with just a single red rectangle in the center acting as a button would look something like this:

import UIKit
import SpriteKit
class ButtonTestScene: SKScene {
    var button: SKNode! = nil
    override func didMove(to view: SKView) {
        // Create a simple red rectangle that's 100x44
        button = SKSpriteNode(color: .red, size: CGSize(width: 100, height: 44))
        // Put it in the center of the scene
        button.position = CGPoint(x:self.frame.midX, y:self.frame.midY);
        self.addChild(button)
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        // Loop over all the touches in this event
        for touch in touches {
            // Get the location of the touch in this scene
            let location = touch.location(in: self)
            // Check if the location of the touch is within the button's bounds
            if button.contains(location) {
                print("tapped!")
            }
        }
    }
}

If you need a button that looks and animates like the ones in UIKit, you'll need to implement that yourself; there's nothing built in to SpriteKit.

Bhavin p
  • 98
  • 10
Mike S
  • 41,895
  • 11
  • 89
  • 84
15

I have created a class SgButton (https://github.com/nguyenpham/sgbutton) in Swift to create buttons for SpriteKit. You can create buttons with images, textures (from SpriteSheet), text only, text and background images/texture. For example, to create button with image:

SgButton(normalImageNamed: "back.png")

Create button with textures:

SgButton(normalTexture: buttonSheet.buy(), highlightedTexture: buttonSheet.buy_d(), buttonFunc: tappedButton)

Create round corner text button:

SgButton(normalString: "Tap me", normalStringColor: UIColor.blueColor(), size: CGSizeMake(200, 40), cornerRadius: 10.0, buttonFunc: tappedButton)
Tony
  • 1,551
  • 20
  • 21
  • Why would this be downvoted? Don't you guy respect the contribution from other people? – Tony May 09 '15 at 01:06
  • I'm using your solution and it works great - not sure why this was originally down voted. – Shawn J. Molloy May 19 '15 at 19:36
  • 5
    @Tony worry non, your class is very good, it only need a few updates to work with the latest syntax and UITouch changes introduced... – Juan Boero Nov 25 '15 at 00:18
  • I cannot use SgButton now. After I import it by pod, build failed. I don't know whether I can edit it in xcode or not. Hope it works. – Dong Wang Oct 11 '21 at 13:04
3

Mike S - Answer updated for - Swift 5.2

override func didMove(to view: SKView) {
        createButton()
        
    }

func createButton()
    {
        // Create a simple red rectangle that's 100x44
        button = SKSpriteNode(color: SKColor.red, size: CGSize(width: 100, height: 44))
        // Put it in the center of the scene
        button.position = CGPoint(x:self.frame.midX, y:self.frame.midY);
        
        self.addChild(button)
        
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        let touchLocation = touch!.location(in: self)
            // Check if the location of the touch is within the button's bounds
            if button.contains(touchLocation) {
                print("tapped!")
            }
        
    }
uplearned.com
  • 3,393
  • 5
  • 44
  • 59
  • This works, if the "button" is a child of the SKView, however if one makes the button the child of another SKSpriteNode or a camera, then this does not work. – SumNeuron Jan 15 '17 at 16:31
1

You can use OOButtonNode. Text/Image buttons, Swift 4.

Oleg O
  • 11
  • 2
  • 2
    Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. See [how to answer](https://stackoverflow.com/help/how-to-answer) – SilverNak Feb 26 '18 at 17:01
  • I think that all necessary information is in this topic. According to context this link direct to library on the GitHub with SpriteKit button implementation :-) – Oleg O Feb 27 '18 at 15:18
-6
          func tappedButton(theButton: UIButton!) {
                println("button tapped")
           }
        }

The above code prints out button tapped when the button is tapped.

P.S. the swift ebook is a really good guide for the new programming language.