By MatterGoal

2011-03-31 13:07:19 8 Comments

I'd like to subclass UIButton to add some properties that i need (not methods... only properties).

Here the code of my subclass:

@interface MyButton : UIButton{
    MyPropertyType *property;

@property (nonatomic,retain) MyPropertyType *property;

@implementation MyButton
@synthesize property;


And here how I use the class:

MyButton *btn = ((MytButton *)[MyButton buttonWithType:UIButtonTypeRoundedRect]); = SomeDataForTheProperty;

From where i obtain this error :

 -[UIRoundedRectButton setProperty:]: unrecognized selector sent to instance 0x593e920

Thus, from ButtonWithType i obtain a UIRoundedRectButton and (Mybutton *) can't cast it... What i have to do to obtain a MyButton object ? is -init the unique solution ?

Thank you!


@Joe 2011-03-31 13:21:22

Try using a category with Associative References instead. It is much cleaner and will work on all instances of UIButton.


#import <Foundation/Foundation.h>

@interface UIButton(Property)

@property (nonatomic, retain) NSObject *property;



#import "UIButton+Property.h"
#import <objc/runtime.h>

@implementation UIButton(Property)

static char UIB_PROPERTY_KEY;

@dynamic property;

-(void)setProperty:(NSObject *)property
    objc_setAssociatedObject(self, &UIB_PROPERTY_KEY, property, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    return (NSObject*)objc_getAssociatedObject(self, &UIB_PROPERTY_KEY);


//Example usage

#import "UIButton+Property.h"


UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; = @"HELLO";
NSLog(@"Property %@",; = nil;
NSLog(@"Property %@",;

@Joe 2011-03-31 13:27:55

I used NSObject but the type can be any type you define including MyPropertyType also UIButton(Property) is really generic consider renaming property to something more useful.

@MatterGoal 2011-04-04 09:04:45

This's a clean way to do exactly what i'm asking for :) thank you

@Chris Brandsma 2011-06-21 18:43:19

I didn't use your answer, but I learned something new (objc_setAssociatedObject). So thank you.

@roocell 2011-12-25 14:43:43

excellent - this works great for using UIButtonTypeContactAdd at the end of a row and passing objects. (when .tag isn't sufficient).

@Anonymous White 2012-10-28 12:00:40

Does this work for iOS5?

@Anonymous White 2012-10-28 12:01:10

where did you initialize static char UIB_PROPERTY_KEY;?

@Joe 2012-10-28 12:31:31

You do not need to initialize it, the address is the key.

@Anonymous White 2012-10-28 12:54:03

all we care is that it's different. Also can we combine this with sub classing for truly elegant solution.

@Anonymous White 2012-10-28 13:11:58

Looks like this thing won't work with subclassing isn't it. For all IOS know the object is of type UIButton and unless you add the category to the class, which would defeat the purpose of encapsulating, it'll still complain.

@AdamM 2012-11-13 16:37:07

This solution worked great for me, originally I was going to subclass, but this method is soo much cleaner. Cheers!!!

@João Nunes 2013-02-11 13:30:07

I dont really think this is a clean solution... This is a hacky solution instead.

@Joe 2013-02-11 14:25:11

@JoãoNunes Care to explain what is "hacky" about a well documented solution?

@João Nunes 2013-02-13 08:07:58

using objc low-level methods is not pretty at all and looks hacky, subclassing is much more objective programming and less confusing.

@David John Smith 2013-07-01 00:49:11

In the case of UIButton I think this is a much better solution than subclassing, as calling buttonWithType: on a subclass will not return an object with the inherited methods.

@João Nunes 2013-12-19 09:47:23

ofc... you have to subclass the initialiser too! To create a different object otherwise you are just creating a UIButton.

@Luke 2014-01-21 04:22:15

Is it allowed - Would an App get approved using this?

@jeet.chanchawat 2015-12-23 12:54:55

For future users: dont miss #import <objc/runtime.h> to avoid getting into this trouble…

@StCredZero 2013-01-24 05:19:43

I have a simple scheme that only involves a few library methods, no boilerplate, and just 3 lines of code for each property you want to add. There are two example properties added below: startPoint and tileState. For illustrative purposes here are the lines you'd need to add for a property like tileState:

//@property (assign, nonatomic) SCZTileState tileState; // tileState line 1 
//@property (assign, nonatomic) SCZTileState tileState; // tileState line 2 
//@dynamic tileState;                                   // tileState line 3

There's more details in my blog post describing how this works


#import <UIKit/UIKit.h>

@interface UIButton (SCZButton)
@property (readwrite, nonatomic) id assocData;


//  UIButton+SCZButton.m
//  Copyright (c) 2013 Ooghamist LLC. All rights reserved.

#import "UIButton+SCZButton.h"
#import <objc/runtime.h>

@implementation UIButton (SCZButton)
- (id)assocData {
    id data = objc_getAssociatedObject(self, "SCZButtonData");
    return data;
- (void)setAssocData:(id)data {
    objc_setAssociatedObject(self, "SCZButtonData", data,  


//  UIButton+OOGTotallyTile.m
//  Copyright (c) 2013 Ooghamist LLC. All rights reserved.
#import <UIKit/UIKit.h>
#import "UIButton+SCZButton.h"
#define kPointLabelTag 837459

typedef enum {
} SCZTileState;

@interface SCZButtonData : NSObject
@property (assign, nonatomic) CGPoint startPoint;
@property (assign, nonatomic) SCZTileState tileState;   // tileState line 1

@interface UIButton (OOGTotallyTile)
@property (readonly, nonatomic) SCZButtonData *buttonData;
@property (assign, nonatomic) CGPoint startPoint;
@property (assign, nonatomic) SCZTileState tileState;  // tileState line 2


//  UIButton+OOGTotallyTile.m
//  Copyright (c) 2013 Ooghamist LLC. All rights reserved.

#import "OOGTotallyTile.h"

@implementation SCZButtonData

@implementation UIButton (OOGTotallyTile)
@dynamic startPoint;
@dynamic tileState; // tileState line 3

- (SCZButtonData*)buttonData {
    if ( ! self.assocData) {
        self.assocData = [[SCZButtonData alloc] init];
    return self.assocData;
- (id)forwardingTargetForSelector:(SEL)aSelector {
    id forwardingTarget = [super forwardingTargetForSelector:aSelector];
    if ( ! forwardingTarget) {
        return [self buttonData];
    return forwardingTarget;

@Wex 2011-03-31 13:12:10

You need to do:

MyButton *btn = [[MyButton alloc] init];

To create your button. The buttonWithType:UIButtonTypeRoundedRect only creates UIButton objects.

=== edit ===

If you wish to use a RoundedRect button; then I would suggest the following. Basically, we just create a UIView with whatever properties we want and add the desired button to that view.


@interface MyButton : UIView
    int property;

@property int property;


@implementation MyButton
@synthesize property;

- (id)initWithFrame:(CGRect)_frame
    self = [super initWithFrame:_frame];
    if (self)
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        btn.frame = self.bounds;
        [self addSubview:btn];
    return self;



MyButton *btn = [[MyButton alloc] initWithFrame:CGRectMake(0, 0, 200, 20)]; = 42;

[self.view addSubview:btn];

@Joe 2011-03-31 15:25:42

Doesn't this method limit you to using buttons of type UIButtonTypeCustom?

@Wex 2011-03-31 15:32:52

Updated my answer.

@Joe 2011-03-31 16:57:17

Now he has no access to any button methods unless he exposes btn through a property.

@Dan Rosenstark 2012-02-09 20:57:50

@Joe: okay, it could be promoted to a property, too. Or you could hide some of the UIButton functionality. Great Facade, Wex.

Related Questions

Sponsored Content

34 Answered Questions

[SOLVED] How do I create a basic UIButton programmatically?

16 Answered Questions

[SOLVED] Set UIButton title UILabel font size programmatically

11 Answered Questions

[SOLVED] How to set the title of UIButton as left alignment?

  • 2010-05-04 11:56:19
  • Madan Mohan
  • 192721 View
  • 444 Score
  • 11 Answer
  • Tags:   objective-c uibutton

3 Answered Questions

[SOLVED] Property not found on object of type

2 Answered Questions

UIButton deallocated issue

2 Answered Questions

[SOLVED] Custom UIButton does not change its image

0 Answered Questions

How to update the selected property of a UIButton using the button's tag

  • 2013-12-11 23:10:43
  • Adam M
  • 210 View
  • 0 Score
  • 0 Answer
  • Tags:   ios uibutton

1 Answered Questions

[SOLVED] custom UIButton, unrecognized selector sent to instance

1 Answered Questions

Sponsored Content