Tôi đã viết thể loại này. Nếu isEqual:
không trả về NO, nó sẽ kiểm tra nếu so sánh thêm các thành phần khác nhau có thể vẫn khớp. Nếu có thể, các mô hình khác nhau vẫn được so sánh.
@implementation UIColor (Matching)
-(BOOL)matchesColor:(UIColor *)color error:(NSError *__autoreleasing *)error
{
UIColor *lhs = self;
UIColor *rhs = color;
if([lhs isEqual:rhs]){ // color model and values are the same
return YES;
}
CGFloat red1, red2, green1, alpha1, green2, blue1, blue2, alpha2;
BOOL lhsSuccess = [lhs getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
BOOL rhsSuccess = [rhs getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];
if((!lhsSuccess && rhsSuccess) || (lhsSuccess && !rhsSuccess)){ // one is RGBA, one color not.
CGFloat r,g,b,a;
if(!lhsSuccess){ // lhs color could be a monochrome
const CGFloat *components = CGColorGetComponents(lhs.CGColor);
if([lhs _colorSpaceModel] == kCGColorSpaceModelMonochrome){
r = g = b = components[0];
a = components[1];
return r == red2 && g == green2 && b == blue2 && a == alpha2;
}
} else { // rhs color could be a monochrome
const CGFloat *components = CGColorGetComponents(rhs.CGColor);
if([rhs _colorSpaceModel] == kCGColorSpaceModelMonochrome){
r = g = b = components[0];
a = components[1];
return r == red1 && g == green1 && b == blue1 && a == alpha1;
}
}
NSError *aError = [[NSError alloc] initWithDomain:@"UIColorComparision" code:-11111 userInfo:[self _colorComparisionErrorUserInfo]];
*error = aError;
return NO;
} else if (!lhsSuccess && !rhsSuccess){ // both not RGBA, lets try HSBA
CGFloat hue1,saturation1,brightness1;
CGFloat hue2,saturation2,brightness2;
lhsSuccess = [lhs getHue:&hue1 saturation:&saturation1 brightness:&brightness1 alpha:&alpha1];
rhsSuccess = [lhs getHue:&hue2 saturation:&saturation2 brightness:&brightness2 alpha:&alpha2];
if((!lhsSuccess && rhsSuccess) || (lhsSuccess && !rhsSuccess)){
NSError *aError = [[NSError alloc] initWithDomain:@"UIColorComparision" code:-11111 userInfo:[self _colorComparisionErrorUserInfo]];
*error = aError;
return NO;
} else if(!lhsSuccess && !rhsSuccess){ // both not HSBA, lets try monochrome
CGFloat white1, white2;
lhsSuccess = [lhs getWhite:&white1 alpha:&alpha1];
rhsSuccess = [rhs getWhite:&white2 alpha:&alpha2];
if((!lhsSuccess && rhsSuccess) || (lhsSuccess && !rhsSuccess)){
NSError *aError = [[NSError alloc] initWithDomain:@"UIColorComparision" code:-11111 userInfo:[self _colorComparisionErrorUserInfo]];
*error = aError;
return NO;
} else {
return white1 == white2 && alpha1 == alpha2;
}
} else {
return hue1 == hue2 && saturation1 == saturation2 && brightness1 == brightness2 && alpha1 == alpha2;
}
} else {
return (red1 == red2 && green1 == green2 && blue1 == blue2 && alpha1 == alpha2);
}
}
-(NSDictionary *)_colorComparisionErrorUserInfo{
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Comparision failed.", nil),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The colors models are incompatible. Or the color is a pattern.", nil),
};
return userInfo;
}
- (CGColorSpaceModel)_colorSpaceModel {
return CGColorSpaceGetModel(CGColorGetColorSpace(self.CGColor));
}
@end
UIColor *green1 = [UIColor greenColor];
UIColor *green2 = [UIColor colorWithRed:0 green:1 blue:0 alpha:1];
UIColor *yellow = [UIColor yellowColor];
UIColor *grey1 = [UIColor colorWithWhite:2.0/3.0 alpha:1];
UIColor *grey2 = [UIColor lightGrayColor];
NSError *error1, *error2, *error3, *error4, *error5;
BOOL match1 = [green1 matchesColor:green2 error:&error1]; // YES
BOOL match2 = [green1 matchesColor:yellow error:&error2]; // NO
BOOL match3 = [green1 matchesColor:grey1 error:&error3]; // NO
BOOL match4 = [grey1 matchesColor:grey2 error:&error4]; // YES
BOOL match5 = [grey1 matchesColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]]
error:&error5]; // NO, Error