Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't subclass UIColor?

I'm trying to subclass UIColor, and I can't seem to figure out what's wrong.

In my PColor.h

#import <Foundation/Foundation.h>
@interface PColor : UIColor {
    BOOL isAvailable;
    int colorId;
}
@property (nonatomic, assign) BOOL isAvailable;
@property (nonatomic, assign) int colorId;
@end

...and in my PColor.m

#import "PColor.h"

@implementation PColor
@synthesize isAvailable;
@synthesize colorId;
@end

Upon instantiating a PColor object, I get:

//warning: incompatible Objective-C types initializing 'struct UIColor *', expected 'struct PColor *'
PColor *pcolor = [[PColor alloc] initWithHue:1 saturation:0 brightness:0 alpha:1];

Am I missing something? Thanks in advance.

like image 754
Chazbot Avatar asked Feb 04 '26 02:02

Chazbot


2 Answers

UIColor is a class cluster use associative references in a category to add properties! All of the custom init methods on UIColor return a UIColor* not an id so you can not easily subclass UIColor nor should you try.

UIColor+PCOLOR.h

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

@interface UIColor(PCOLOR)
//Properties prefixed to try and avoid future conflicts
@property (nonatomic, assign) BOOL pIsAvailable;
@property (nonatomic, assign) int pColorId;
@end

UIColor+PCOLOR.h

#import "UIColor+PCOLOR.h"

@implementation UIColor(PCOLOR)

static char PCOLOR_ISAVAILABLE_KEY;
static char PCOLOR_COLORID_KEY;

@dynamic pIsAvailable, pColorId;

-(void)setPIsAvailable:(BOOL)pIsAvailable
{
    objc_setAssociatedObject(self, &PCOLOR_ISAVAILABLE_KEY, [NSNumber numberWithBool:pIsAvailable], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(BOOL)pIsAvailable
{
    return [(NSNumber*)objc_getAssociatedObject(self, &PCOLOR_ISAVAILABLE_KEY) boolValue];
}

-(void)setPColorId:(int)pColorId
{
    objc_setAssociatedObject(self, &PCOLOR_COLORID_KEY, [NSNumber numberWithInt:pColorId], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(int)pColorId
{
    return  [(NSNumber*)objc_getAssociatedObject(self, &PCOLOR_COLORID_KEY) intValue];
}

@end

USAGE

UIColor *pcolor = [[UIColor alloc] initWithHue:1 saturation:0 brightness:0 alpha:1];
pcolor.pColorId = 2352;
pcolor.pIsAvailable = YES;
NSLog(@"\nClass: %@\nColor ID: %d\nIs Availabled: %@", 
      NSStringFromClass([pcolor class]), 
      pcolor.pColorId, 
      pcolor.pIsAvailable ? @"YES" : @"NO");
[pcolor release];
like image 185
Joe Avatar answered Feb 06 '26 17:02

Joe


From UIColor Class Reference:

Most developers should have no need to subclass UIColor. The only time doing so might be necessary is if you require support for additional colorspaces or color models.

You should use Category. For example:

@interface UIColor (PColor)
    - (BOOL) isAvailable;
    - (int) colorId;
@end

In the implementation file:

@implementation UIColor (PColor)

    - (BOOL)isAvailable {
        // do what you want to do
        // return your BOOL
    }

    - (int)colorId  {
        // do what you want to do
        // return id of color
    }

@end
like image 42
Black Frog Avatar answered Feb 06 '26 18:02

Black Frog



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!