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