7

In Swift, how do I execute the Cocoa target-action pattern with a selector determined at runtime?

The specifics at hand: My code receives a UIBarButtonItem, and it needs invoke the action that button represents. In Objective-C, it's straightforward:

UIBarButtonItem* button = ...;
[button.target performSelector: button.action withObject: self];

In Swift, performSelector: is not exposed for type/memory safety reasons. I can't create a Swift closure since I don't know the button.action at compile time. Any other technique for invoking the action?

Jay Lieske
  • 4,788
  • 3
  • 30
  • 41

2 Answers2

16

This was answered in the Apple Developer Forums:

Use UIApplication.sendAction(_:to:from:forEvent:). Technically, you should be using that even in Objective-C, because it understands the various kinds of parameters an action can take and passes them for you.

Here's the code I ended up using:

UIApplication.sharedApplication()
    .sendAction(button.action, to: button.target,
                from: self, forEvent: nil)

It has the same effect as @vladof's answer, but it saves allocating the UIControl.

Jay Lieske
  • 4,788
  • 3
  • 30
  • 41
3

Suppose there is a method in Objective C class TestClass that returns a UIBarButtonItem:

- (UIBarButtonItem *)getBarButtonItem
{
    UIBarButtonItem *bar = [[UIBarButtonItem alloc] init];
    bar.target = self;
    bar.action = @selector(help);
    return bar;
}

- (void)help
{
    NSLog(@"Help offered");
}

In Swift:

var testClass = TestClass()
var barButtonItem = testClass.getBarButtonItem()
var button: UIButton = UIButton()
button.sendAction(barButtonItem.action, to: barButtonItem.target, forEvent: nil)

Console log:

2014-07-06 23:49:49.942 TestApp [53986:2552835] Help offered

Also note that we can instantiate UIControl instead of UIButton.

vladof81
  • 26,121
  • 9
  • 38
  • 41
  • Alternative: (Just to keep the posts in-sync) There is another approach to invoke action on target using `NSThread.detachNewThreadSelector`, please refer to [this question](http://stackoverflow.com/a/24602971/2920335). – vladof81 Jul 08 '14 at 03:48