Subclass UIButton to add a property Subclass UIButton to add a property ios ios

Subclass UIButton to add a property


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

UIButton+Property.h

#import <Foundation/Foundation.h>@interface UIButton(Property)@property (nonatomic, retain) NSObject *property;@end

UIButton+Property.m

#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);}-(NSObject*)property{    return (NSObject*)objc_getAssociatedObject(self, &UIB_PROPERTY_KEY);}@end

//Example usage

#import "UIButton+Property.h"...UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];button1.property = @"HELLO";NSLog(@"Property %@", button1.property);button1.property = nil;NSLog(@"Property %@", button1.property);


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.


.h

@interface MyButton : UIView{    int property;}@property int property;@end

.m

@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;}@end

Usage:

MyButton *btn = [[MyButton alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];btn.property = 42;[self.view addSubview:btn];


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

UIButton+SCZButton.h

#import <UIKit/UIKit.h>@interface UIButton (SCZButton)@property (readwrite, nonatomic) id assocData;@end

UIButton+SCZButton.m

//  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,                               OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end

OOGTotallyTile.h

//  UIButton+OOGTotallyTile.m//  Copyright (c) 2013 Ooghamist LLC. All rights reserved.#import <UIKit/UIKit.h>#import "UIButton+SCZButton.h"#define kPointLabelTag 837459typedef enum {    SCZTileStatePlaced,    SCZTileStateDropping,    SCZTileStateDropped} SCZTileState;@interface SCZButtonData : NSObject@property (assign, nonatomic) CGPoint startPoint;@property (assign, nonatomic) SCZTileState tileState;   // tileState line 1@end@interface UIButton (OOGTotallyTile)@property (readonly, nonatomic) SCZButtonData *buttonData;@property (assign, nonatomic) CGPoint startPoint;@property (assign, nonatomic) SCZTileState tileState;  // tileState line 2@end

OOGTotallyTile.m

//  UIButton+OOGTotallyTile.m//  Copyright (c) 2013 Ooghamist LLC. All rights reserved.#import "OOGTotallyTile.h"@implementation SCZButtonData@end@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;}@end