I’ve always been a little vague on how to make a subclass of UIButton, so here’s how you do it properly.

How iOS7 changed my approach

Prior to iOS7, you could get away with simply overriding init, and calling [[MyButton alloc] init]. This would basically get you a UIButtonTypeCustom, which was what you usually wanted, job done. However, iOS7 has UIButtonTypeSystem, which you don’t get if you simply override init. And UIButtonTypeSystem has a few desirable features, such as respecting tintColor and the finger-up fade animation. So overriding init doesn’t cut it any more.

My new approach

Basically, the magic is that the built-in buttonWithType method, when called on a subclass, returns an instance of that subclass - it doesn’t just return a UIButton.

Make your header file like so:

@interface MyButton : UIButton
@end

Your implementation (.m file) like so:

@implementation MyButton
 
+ (instancetype)buttonWithType:(UIButtonType)buttonType {
    MyButton *button = [super buttonWithType:buttonType];
    [button postButtonWithTypeInit];
    return button;
}
 
/// Because we can't override init on a uibutton, do init steps here.
- (void)postButtonWithTypeInit {
    [self setTitle...
}

/// Make your button have a custom appearance when highlighted here.
- (void)setHighlighted:(BOOL)highlighted {
	[super setHighlighted:highlighted];
	...
}

And put everything that you need at creation time in your postButtonWithTypeInit, and your custom highlight style in setHighlighted.

To create an instance of your new button, simply do as you would with a normal UIButton:

MyButton *button = [MyButton buttonWithType:UIButtonTypeSystem];

Caveat

The only caveat with this method is that the UIButton docs explicitly say the following regarding buttonWithType:

If you subclass UIButton, this method does not return an instance of your subclass. If you want to create an instance of a specific subclass, you must alloc/init the button directly.

However, this does not appear to be the case. And their advice to use init directly is unhelpful in iOS7 because it makes it impossible to create a subclassed UIButtonTypeSystem.

Thanks for reading! And if you want to get in touch, I'd love to hear from you: chris.hulbert at gmail.

Chris Hulbert

(Comp Sci, Hons - UTS)

Software Developer (Freelancer / Contractor) in Australia.

I have worked at places such as Google, Cochlear, Assembly Payments, News Corp, Fox Sports, NineMSN, FetchTV, Coles, Woolworths, Trust Bank, and Westpac, among others. If you're looking for help developing an iOS app, drop me a line!

Get in touch:
[email protected]
github.com/chrishulbert
linkedin



 Subscribe via RSS