34 votes

Sous-classe UIButton pour ajouter une propriété

J'aimerais sous-classe UIButton ajouter quelques propriétés que j'ai besoin (pas de méthodes... seules les propriétés).

Voici le code de mon sous-classe:

//.h-----------------------
@interface MyButton : UIButton{
    MyPropertyType *property;
}

@property (nonatomic,retain) MyPropertyType *property;
@end

//.m--------------------------
@implementation MyButton
@synthesize property;

@end

Et voici comment j'utilise la classe:

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

De là où je obtenir cette erreur :

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

Ainsi, à partir de ButtonWithType - je obtenir un UIRoundedRectButton et (Mybutton *) ne peut pas le jeter... Ce que j'ai à faire pour obtenir un MyButton objet ? est - -init l'unique solution ?

Merci!!!!

87voto

Joe Points 37343

Essayez plutôt d’utiliser une catégorie avec des références associatives . Il est beaucoup plus propre et fonctionnera dans toutes les instances de 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
 

// Exemple d'utilisation

 #import "UIButton+Property.h"

...

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

12voto

Wex Points 1823

Tu as besoin de faire:

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

Pour créer votre bouton. Les buttonWithType:UIButtonTypeRoundedRect ne créent que des objets UIButton.

=== modifier ===

Si vous souhaitez utiliser un bouton RoundedRect; alors je suggérerais ce qui suit. Fondamentalement, nous créons simplement un UIView avec les propriétés que nous voulons et ajoutons le bouton souhaité à cette vue.


.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];
 

2voto

StCredZero Points 334

J'ai un schéma simple qui ne nécessite que de quelques méthodes de bibliothèques, pas de passe-partout, et à seulement 3 lignes de code pour chaque propriété que vous souhaitez ajouter. Il y a deux exemple les propriétés ajoutées ci-dessous: point de départ et tileState. À des fins d'illustration voici les lignes que vous devez ajouter pour un bien comme tileState:

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

Il n'y a plus de détails dans mon post de blog décrivant comment cela fonctionne

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 837459

typedef 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X