Button class: How to send arguments with function

I have a simple Button class in a parent scene that runs a function when tapped. It works perfectly now, as you pass the function name to the Button when creating it. However, to provide a bit more flexibility, I would like to pass arguments with the function, so that I could run e.g. myFunction(argument: Int) rather than myFunction1, myFunction2, ... I remember with Obj-C it would happen through using Selectors, but I never fully understood them earlier, either.


How do I change my Button class to allow the passing of arguments along with the function?


Button.swift

import SpriteKit

class Button: SKNode {

    var background: SKSpriteNode?
    var action: () -> Void

    init(buttonSize: CGSize, buttonBackgroundColor: SKColor, buttonAction: () -> Void) {
        action = buttonAction
  
        super.init()
  
        userInteractionEnabled = true
  
        background = SKSpriteNode(color: buttonBackgroundColor, size: buttonSize)
        addChild(background!)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let location = touches.first?.locationInNode(self) {
            if background!.containsPoint(location) { action() }
        }
    }
}


Scene.swift

let button: Button = Button(buttonSize: CGSize(width: 100.0, height: 100.0), buttonBackgroundColor: SKColor.whiteColor(), buttonAction: myFunction)
addChild(button)


func myFunction() {
     // Do something!
}
Answered by OOPer in 105026022

You can pass a closure without modifying you Button class:

        let button: Button = Button(buttonSize: CGSize(width: 100.0, height: 100.0),
            buttonBackgroundColor: SKColor.whiteColor(),
            buttonAction: {() in self.funcWithArgs("X")})
//...
  
    func funcWithArgs(arg1: String) {
        // Do something more!
    }
Accepted Answer

You can pass a closure without modifying you Button class:

        let button: Button = Button(buttonSize: CGSize(width: 100.0, height: 100.0),
            buttonBackgroundColor: SKColor.whiteColor(),
            buttonAction: {() in self.funcWithArgs("X")})
//...
  
    func funcWithArgs(arg1: String) {
        // Do something more!
    }

Nice! Thanks a lot, OOPer! Your solution worked like a charm 🙂.

Button class: How to send arguments with function
 
 
Q