Reputation: 11171
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
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