How to compare UIColors?

2019-01-03 02:33发布

I'd like to check the color set for a background on a UIImageView. I've tried:

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

but that doesn't work, even when I know the color is green, it always falls into the else part.

Also, is there a way to output the current color in the debug console.

p [myimage backgroundColor]

and

po [myimage backgroundColor]

don't work.

17条回答
时光不老,我们不散
2楼-- · 2019-01-03 03:08

Here is an extension to switch to the RGC Space Color in Swift:

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
}

}

查看更多
看我几分像从前
3楼-- · 2019-01-03 03:11

When you're comparing myimage.backgroundColor == [UIColor greenColor] like this if you havent change the backgroundColor to green before that statement it is not working.

I had same problem in my color game and i solved that by using simple difference equation in RGB colors you can quick take a look that short code sample ColorProcess from here

its like victors answer

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{
…
}

Instead of that code sample you can use

include "UIColorProcess.h"

..

float distance = [UIColorProcess findDistanceBetweenTwoColor:[UIColor redColor] secondColor:[UIColor blueColor]];

and of course if it returns 0 that means you are comparing too similar color. return range is something like (0.0f - 1.5f)..

查看更多
狗以群分
4楼-- · 2019-01-03 03:12

Extension to UIColor, using Swift 2.2 features. Note however that because the R G B A values are compared, and these are CGFloat, rounding errors can make that the colours are non returned as equal if they are not exactly the same (e.g. they have not been originally created using the exact same properties in the init(...)!).

/**
 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
}
查看更多
疯言疯语
5楼-- · 2019-01-03 03:14

As zoul pointed out in the comments, isEqual: will return NO when comparing colors that are in different models/spaces (for instance #FFF with [UIColor whiteColor]). I wrote this UIColor extension that converts both colors to the same color space before comparing them:

- (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];
}
查看更多
ゆ 、 Hurt°
6楼-- · 2019-01-03 03:16

I have converted raf's answer to Swift 4 (lots of changes in the CGColor API), removed force unwrapping and decreased indentation thanks to generous use of guard:

@extension UIColor {
    func isEqualToColor(otherColor: UIColor) -> Bool {
        if self == otherColor {
            return true
        }
        let colorSpaceRGB = CGColorSpaceCreateDeviceRGB()
        let convertColorToRGBSpace: ((UIColor) -> UIColor?) = { (color) -> UIColor? in
            guard color.cgColor.colorSpace?.model == .monochrome else {
                return color
            }
            guard let oldComponents = color.cgColor.components else {
                return nil
            }
            let newComponents = [oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]]
            guard let colorRef = CGColor(colorSpace: colorSpaceRGB, components: newComponents) else {
                    return nil
            }
            return UIColor(cgColor: colorRef)
        } 

        guard let selfColor = convertColorToRGBSpace(self), 
              let otherColor = convertColorToRGBSpace(otherColor) else {
            return false
        }
        return selfColor.isEqual(otherColor)
    }
}
查看更多
男人必须洒脱
7楼-- · 2019-01-03 03:19

I'm using this extension which is working for me in all cases.

/***** 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 ****/

Hope helps some one.

Note: #ffffff does equal [UIColor whiteColor] by this extension

查看更多
登录 后发表回答