11

I have a condition in my app where user can choose 3 colors, but those colors should not match with each other, the problem is user can choose the similar color from the pallet for all 3 fields.

I'm trying below code, here color2 has slightly different value of 'green' than color1 :-

UIColor *color1 = [UIColor colorWithRed:1 green:(CGFloat)0.4 blue:1 alpha:1];
UIColor *color2 = [UIColor colorWithRed:1 green:(CGFloat)0.2 blue:1 alpha:1];

 if ([color1 isEqual:color2]) {
        NSLog(@"equals");
    }else {
        NSLog(@"not equal");
    }

output: 'not equal' This is correct by logic because it compares RGB value but I want to check range of it, Let me know if anyone knows how to compare the similar colors.

Shrejas
  • 468
  • 1
  • 4
  • 15
  • 2
    Try `CGColorEqualToColor(<#CGColorRef color1#>, <#CGColorRef color2#>);` – Buntylm Feb 07 '14 at 07:51
  • Method has description :- "Two colors are equal if they have equal color spaces and numerically equal color components." It returns false, may be its unable to check color space, not sure. – Shrejas Feb 07 '14 at 07:54

5 Answers5

34

You need a tolerance, the value of which, only you can decide:

- (BOOL)color:(UIColor *)color1
isEqualToColor:(UIColor *)color2
withTolerance:(CGFloat)tolerance {

    CGFloat r1, g1, b1, a1, r2, g2, b2, a2;
    [color1 getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
    [color2 getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
    return
        fabs(r1 - r2) <= tolerance &&
        fabs(g1 - g2) <= tolerance &&
        fabs(b1 - b2) <= tolerance &&
        fabs(a1 - a2) <= tolerance;
}

...

UIColor *color1 = [UIColor colorWithRed:1 green:(CGFloat)0.4 blue:1 alpha:1];
UIColor *color2 = [UIColor colorWithRed:1 green:(CGFloat)0.2 blue:1 alpha:1];

if ([self color:color1 isEqualToColor:color2 withTolerance:0.2]) {
    NSLog(@"equals");
} else {
    NSLog(@"not equal");
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • You beat me to it! Though, I would probably use || instead of && as only one element needs to be different enough to create a whole new colour. – Dave Wood Feb 07 '14 at 07:59
  • @DaveWood Sorry, I don't follow what you mean WRT `||`/`&&`. The `return` statement will short-circuit as soon as soon as a colour falls outside of a tolerance. – trojanfoe Feb 07 '14 at 08:00
  • 1
    You're right sorry. I jumped the gun as the version I was typing up was testing not equal (and not in a nice function like you did). :) – Dave Wood Feb 07 '14 at 08:03
  • 1
    Beat me to it also, with a more complete answer! – jrturton Feb 07 '14 at 08:05
  • although correct, this answer is way too complicated than what it needs to be. Mani answer below is easier & better – Sam B Jul 05 '15 at 17:26
  • 1
    @SamB How is Mani's code different to the code provided by the OP, which is causing him problems? – trojanfoe Jul 09 '15 at 14:02
13

trojanfoe's answer is great, here is a Swift version:

My suggestion: Create an extension on UIColor like so:

public extension UIColor{

    func isEqualToColor(color: UIColor, withTolerance tolerance: CGFloat = 0.0) -> Bool{

        var r1 : CGFloat = 0
        var g1 : CGFloat = 0
        var b1 : CGFloat = 0
        var a1 : CGFloat = 0
        var r2 : CGFloat = 0
        var g2 : CGFloat = 0
        var b2 : CGFloat = 0
        var a2 : CGFloat = 0

        self.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
        color.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)

        return
            fabs(r1 - r2) <= tolerance &&
            fabs(g1 - g2) <= tolerance &&
            fabs(b1 - b2) <= tolerance &&
            fabs(a1 - a2) <= tolerance
    }

}

Usage:

// check if label's color is white
if label.textColor.isEqualToColor(UIColor.whiteColor(), /* optional */ withTolerance: 0.0){
    // if so, add shadow
    label.layer.shadowColor = UIColor.blackColor().CGColor
    label.layer.shadowRadius = 4.0
    label.layer.shadowOpacity = 0.6
    label.layer.shadowOffset = CGSizeMake(0, 0)
}
the_critic
  • 12,720
  • 19
  • 67
  • 115
9

You can use this function also.

UIColor *color1 = [UIColor colorWithRed:1 green:(CGFloat)0.4 blue:1 alpha:1];
UIColor *color2 = [UIColor colorWithRed:1 green:(CGFloat)0.2 blue:1 alpha:1];

if (CGColorEqualToColor(color1.CGColor,color2.CGColor))
{
    //Two colors are same
}
Mani
  • 17,549
  • 13
  • 79
  • 100
2

If I understood clearly :

CGFloat *components1 = CGColorGetComponents([[UIColor color1] CGColor]);
CGFloat *component1 = CGColorGetComponents([[UIColor color2] CGColor]);

Then, you can compare the difference between the two colors using components[0] (red),components[1] (green), components[2] (blue) and components[3] alpha. Decide what you wanna compare. Example : fabs(components1[1]-components2[1]), or a mean between all theses differences, etc.

Larme
  • 24,190
  • 6
  • 51
  • 81
1

isEqualTo: works when you initialize UIColor instance by passing float values

UIColor *color1 = [UIColor colorWithRed:1.0f green:0.4f blue:1.0f alpha:1.0f];
UIColor *color2 = [UIColor colorWithRed:1.0f green:0.2f blue:1.0f alpha:1.0f];

 if ([color1 isEqual:color2]) {
     NSLog(@"equals");
 }else {
     NSLog(@"not equal");
 }

 // This will print equals
Burhanuddin Sunelwala
  • 5,318
  • 3
  • 25
  • 51