royhowie
royhowie

Reputation: 11171

How to dynamically add an action to a UIButton

I noticed I had a lot of functions to dynamically add buttons in one of my view controllers, which clearly goes against the DRY principle.

To fix this, I wrote a hit-everything configureButton function:

func configureButton (button: UIButton, action: String, title: String, pos: [CGFloat]) {
    button.addTarget(self, action: action,
            forControlEvents: UIControlEvents.TouchUpInside)
    // ^ throws an error

    // button.addTarget(self, action: "goToScanner",
    //        forControlEvents: UIControlEvents.TouchUpInside)

    /* configure everything else */        

    self.view.addSubview(button)
}

When I had a zillion different functions, I simply wrote something like

button.addTarget(self, action: "goToScanner",    // <-- note the string
        forControlEvents: UIControlEvents.TouchUpInside)

in each of them, where "goToScanner" is the function I want called on tap.

I want to be able to dynamically pass the action parameter for button.addTarget to configureButton:

configureButton(scanButton, action: "goToScanner", title: "Scan", pos: [36.0, 300])

I tried passing a closure () -> (), but that didn't work.

How can I approach this problem?

Upvotes: 2

Views: 619

Answers (1)

Schemetrical
Schemetrical

Reputation: 5536

Your method should be

func configureButton (button: UIButton, action: Selector, title: String, pos: [CGFloat])

Note how it uses Selector instead of String.

This is because Swift has no built in implementation of a Selector, you pass a string and the string literal is type inferred into a Selector (just like how entering a number literal will work as both a int, float, NSNumber, etc).

Upvotes: 2

Related Questions