Reputation: 1098
I want to compare two UIColors that I generated using [UIColor colorWithPatternImage:] for equality. I can't seem to figure out how to do this.
[[UIColor colorWithPatternImage:[UIImage imageNamed:@"camo2"]] isEqual:
[UIColor colorWithPatternImage:[UIImage imageNamed:@"camo2"]]]
Always returns false, whether I use == or isEqual. Does anybody know if it's possible to properly compare colorWithPatternImages, or CGPatterns I suppose? I've also tried comparing CGColorGetPattern(color.CGColor) but that doesn't work either.
EDIT: The reason for this is I have a function that accepts a UIColor and gives me an NSString for displaying to the user.
+(NSString *)colorNameForColor:(UIColor *)color {
if ([color isEqual:[UIColor whiteColor]]) {
return @"White";
}
if ([color isEqual:[UIColor colorWithPatternImage:[UIImage imageNamed:@"camo"]]]) {
return @"Camo";
}
...
}
Is this just an insane thing to do? I suppose I could make my own object that has a color property and a colorName property...
Upvotes: 1
Views: 257
Reputation: 1568
This took some reverse engineering of CoreGraphics
but I was able to find one private method _CGPatternGetImage
which appears to return the image.
You'll need to include the following headers:
#include <dlfcn.h>
@import CoreGraphics;
Create a function pointer:
typedef CGImageRef (*CGPatternGetImage)(CGPatternRef pattern);
And then access the function:
-(void)comparePatterns
{
void *handle = dlopen("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics", RTLD_NOW);
CGPatternGetImage getImage = (CGPatternGetImage) dlsym(handle, "CGPatternGetImage");
UIColor *aColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"pattern1"]];
UIColor *bColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"pattern1"]];
UIColor *cColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"pattern2"]];
NSData *aImageData = UIImagePNGRepresentation([UIImage imageWithCGImage:getImage(CGColorGetPattern(aColor.CGColor))]);
NSData *bImageData = UIImagePNGRepresentation([UIImage imageWithCGImage:getImage(CGColorGetPattern(bColor.CGColor))]);
NSData *cImageData = UIImagePNGRepresentation([UIImage imageWithCGImage:getImage(CGColorGetPattern(cColor.CGColor))]);
NSLog(@"Should be true: %d",[aImageData isEqual:bImageData]);
NSLog(@"Should be false: %d",[aImageData isEqual:cImageData]);
}
You probably don't want to access any private APIs in a production app but this might be useful for testing.
If this is going on the App Store then a better solution could be creating a category for UIColor
and give it an associative reference to store the pattern name or whatever is easiest for you to compare. This won't compare the actual images at all so it's possible that if you don't set the correct data to identify the pattern the comparison won't be accurate.
Include the header:
#import <objc/runtime.h>
Create the category:
@interface UIColor(CustomPatterns)
@property (strong, nonatomic) NSString* patternName;
@end
@implementation UIColor(CustomPatterns)
static char CUSTOM_PATTERNS_PATTERN_NAME_KEY;
@dynamic patternName;
-(void)setPatternName:(NSString *)patternName
{
objc_setAssociatedObject(self, &CUSTOM_PATTERNS_PATTERN_NAME_KEY, patternName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)patternName
{
return (NSString*)objc_getAssociatedObject(self, &CUSTOM_PATTERNS_PATTERN_NAME_KEY);
}
@end
And then you can set your custom data and compare:
-(void)comparePatterns
{
UIColor *aColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"1"]];
aColor.patternName = @"1";
UIColor *bColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"1"]];
bColor.patternName = @"1";
UIColor *cColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"2"]];
cColor.patternName = @"2";
NSLog(@"Should be true: %d",[aColor.patternName isEqualToString:bColor.patternName]);
NSLog(@"Should be false: %d",[aColor.patternName isEqualToString:cColor.patternName]);
}
Upvotes: 1