Skip to content

Instantly share code, notes, and snippets.

@johnhatvani
Last active October 10, 2021 04:34
Show Gist options
  • Save johnhatvani/9404803 to your computer and use it in GitHub Desktop.
Save johnhatvani/9404803 to your computer and use it in GitHub Desktop.
Objective-c runtime fun -- A UIButton that takes a block as an action. The cool thing it does is it adds this action as an instance method at runtime.
#import <objc/runtime.h>
typedef void (^buttonAction)(UIButton *sender);
@implementation UIButton (BlockAction)
+ (UIButton *) buttonWithType:(UIButtonType)type andAction:(buttonAction)action forControlEvents:(UIControlEvents)controlEvents; {
UIButton * button = [UIButton buttonWithType:type];
// suppress undeclared selector warning or else '@selector(action:)' will complain.
// because it doesnt actually exist...yet.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
// pull out IMP implementation from the block.
IMP blockImp = imp_implementationWithBlock(action);
// add the instance method with the name 'action:' and the arguement type of UIBUttion *
class_addMethod(UIButton.class, @selector(action:), blockImp, @encode(UIButton *));
// add action like you normally would.
[button addTarget:button action:@selector(action:) forControlEvents:controlEvents];
#pragma clang diagnostic pop
return button;
}
@johnhatvani
Copy link
Author

UIButtion+BlockAction

Simple easy to use UIButton category that allows you to add an action as a block. The category utilises the Objective-c runtime to add a method and implementation to the UIButton instance.

Usage:

UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom andAction:^(UIButton *sender) {

       //... code here

    } forControlEvents:UIControlEventTouchUpInside];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment