如何比较UIColors?

我想检查在UIImageView背景的颜色设置。 我试过了:

if(myimage.backgroundColor == [UIColor greenColor]){ ...} else{ ...} 

但即使我知道颜色是绿色的,它也不起作用,它总是落入其他部分。

另外,有没有办法在debugging控制台中输出当前的颜色。

 p [myimage backgroundColor] 

 po [myimage backgroundColor] 

不工作。

你尝试过[myColor isEqual:someOtherColor]

正如zoul在评论中指出的那样, isEqual:在比较不同模型/空间的颜色(例如#FFF[UIColor whiteColor] )时将返回NO 。 我写了这个UIColor扩展名,将两种颜色转换为相同的颜色空间,然后再比较它们:

 - (BOOL)isEqualToColor:(UIColor *)otherColor { CGColorSpaceRef colorSpaceRGB = CGColorSpaceCreateDeviceRGB(); UIColor *(^convertColorToRGBSpace)(UIColor*) = ^(UIColor *color) { if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) == kCGColorSpaceModelMonochrome) { const CGFloat *oldComponents = CGColorGetComponents(color.CGColor); CGFloat components[4] = {oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]}; CGColorRef colorRef = CGColorCreate( colorSpaceRGB, components ); UIColor *color = [UIColor colorWithCGColor:colorRef]; CGColorRelease(colorRef); return color; } else return color; }; UIColor *selfColor = convertColorToRGBSpace(self); otherColor = convertColorToRGBSpace(otherColor); CGColorSpaceRelease(colorSpaceRGB); return [selfColor isEqual:otherColor]; } 

这可能有点晚了,但CoreGraphics有一个更简单的API来实现这一点:

 CGColorEqualToColor(myColor.CGColor, [UIColor clearColor].CGColor) 

就像文件说的那样:

指示两种颜色是否相等。 如果两种颜色具有相同的颜色空间和数字上相同的颜色分量,则两种颜色相等

这解决了很多麻烦和泄漏/自定义algorithm。

 #import "UIColor-Expanded.h" //https://github.com/thetaplab/uicolor-utilities //RGB distance CGFloat distance = sqrtf(powf((clr0.red - clr1.red), 2) + powf((clr0.green - clr1.green), 2) + powf((clr0.blue - clr1.blue), 2) ); if(distance<=minDistance){ .... }else{ ... } 

samvermette的解答翻译成swift:

 extension UIColor { func isEqualToColor(otherColor : UIColor) -> Bool { if self == otherColor { return true } let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() let convertColorToRGBSpace : ((color : UIColor) -> UIColor?) = { (color) -> UIColor? in if CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) == CGColorSpaceModel.Monochrome { let oldComponents = CGColorGetComponents(color.CGColor) let components : [CGFloat] = [ oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1] ] let colorRef = CGColorCreate(colorSpaceRGB, components) let colorOut = UIColor(CGColor: colorRef!) return colorOut } else { return color; } } let selfColor = convertColorToRGBSpace(color: self) let otherColor = convertColorToRGBSpace(color: otherColor) if let selfColor = selfColor, otherColor = otherColor { return selfColor.isEqual(otherColor) } else { return false } } } 

我写了这个类别。 如果isEqual:返回NO,它将testing是否进一步比较不同的组件可能仍然匹配。 如果可能的话,仍然会比较不同的型号。

 @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 

当你比较myimage.backgroundColor == [UIColor greenColor]像这样,如果你没有改变backgroundColor为绿色之前,该语句不工作。

我在我的彩色游戏有同样的问题,我解决了在RGB颜色使用简单的差分方程,你可以快速看看短代码样本ColorProcess从这里

它像胜利者的答案

 GFloat distance = sqrtf(powf((clr0.red - clr1.red), 2) + powf((clr0.green - clr1.green), 2) + powf((clr0.blue - clr1.blue), 2) ); if(distance<=minDistance){ .... }else{ … } 

而不是那个代码示例,你可以使用

 include "UIColorProcess.h" .. float distance = [UIColorProcess findDistanceBetweenTwoColor:[UIColor redColor] secondColor:[UIColor blueColor]]; 

当然如果它返回0意味着你比较太相似的颜色。 返回范围是类似于(0.0f – 1.5f)..

我正在使用这个在所有情况下都适用于我的扩展。

 /***** UIColor Extension to Compare colors as string *****/ @interface UIColor (compare) - (BOOL)compareWithColor:(UIColor *)color; @end @implementation UIColor(compare) - (BOOL)compareWithColor:(UIColor *)color { return ([[[CIColor colorWithCGColor:self.CGColor] stringRepresentation] isEqualToString:[[CIColor colorWithCGColor:color.CGColor] stringRepresentation]]); } @end /**** End ****/ 

希望有助于某人。

注意: [UIColor whiteColor]通过这个扩展名等于[UIColor whiteColor]

关于什么:

 +(BOOL)color:(UIColor *)color1 matchesColor:(UIColor *)color2 { CGFloat red1, red2, green1, green2, blue1, blue2, alpha1, alpha2; [color1 getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1]; [color2 getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2]; return (red1 == red2 && green1 == green2 && blue1 == blue2 && alpha1 == alpha2); } 

一些奇怪的舍入错误可能会发生。 这可能是一个对象设置为一个颜色的原因,你设置的颜色不完全匹配。

这是我解决它的方法:

 private func compareColors (c1:UIColor, c2:UIColor) -> Bool{ // some kind of weird rounding made the colors unequal so had to compare like this var red:CGFloat = 0 var green:CGFloat = 0 var blue:CGFloat = 0 var alpha:CGFloat = 0 c1.getRed(&red, green: &green, blue: &blue, alpha: &alpha) var red2:CGFloat = 0 var green2:CGFloat = 0 var blue2:CGFloat = 0 var alpha2:CGFloat = 0 c2.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2) return (Int(green*255) == Int(green2*255)) } 

这个代码可以通过不仅比较1而是比较所有的组件来改进。 例如红+绿+蓝+ alpha == red2 + green2 + blue2 + alpha2

这是在Swift中切换到RGC空间颜色的扩展:

 extension UIColor { func convertColorToRGBSpaceColor() -> UIColor { let colorSpaceRGB = CGColorSpaceCreateDeviceRGB() let oldComponents = CGColorGetComponents(self.CGColor) let components = [oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]] let colorRef = CGColorCreate(colorSpaceRGB, components) let convertedColor = UIColor(CGColor: colorRef!) return convertedColor } 

}

扩展到UIColor,使用Swift 2.2function。 但是请注意,因为RGBA值被比较,并且这些是CGFloat,所以舍入错误可以使颜色不相等,如果它们不完全相同(例如它们最初没有使用init中完全相同的属性创build(……)!)。

 /** Extracts the RGBA values of the colors and check if the are the same. */ public func isEqualToColorRGBA(color : UIColor) -> Bool { //local type used for holding converted color values typealias colorType = (red : CGFloat, green : CGFloat, blue : CGFloat, alpha : CGFloat) var myColor : colorType = (0,0,0,0) var otherColor : colorType = (0,0,0,0) //getRed returns true if color could be converted so if one of them failed we assume that colors are not equal guard getRed(&myColor.red, green: &myColor.green, blue: &myColor.blue, alpha: &myColor.alpha) && color.getRed(&otherColor.red, green: &otherColor.green, blue: &otherColor.blue, alpha: &otherColor.alpha) else { return false } log.debug("\(myColor) = \(otherColor)") //as of Swift 2.2 (Xcode 7.3.1), tuples up to arity 6 can be compared with == so this works nicely return myColor == otherColor } 

UIColor扩展

 - (CGFloat)accuracyCompareWith:(UIColor *)color { CIColor *c1 = [[CIColor alloc] initWithColor:self]; CIColor *c2 = [[CIColor alloc] initWithColor:color]; BOOL hasAlpha = c1.numberOfComponents == 4 && c2.numberOfComponents == 4; NSInteger numberOfComponents = hasAlpha ? 4 : 3; CGFloat colorMax = 1.0; CGFloat p = colorMax / 100.0; CGFloat redP = fabs(c1.red / p - c2.red / p); CGFloat greenP = fabs(c1.green / p - c2.green / p); CGFloat blueP = fabs(c1.blue / p - c2.blue / p); CGFloat alphaP = 0; if (hasAlpha) alphaP = fabs(c1.alpha / p - c2.alpha / p); return (redP + greenP + blueP + alphaP) / (CGFloat)numberOfComponents; } 
 if([myimage.backgroundColor isEqual:[UIColor greenColor]])