Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two UIColor which have almost same shade or range in iOS?

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.

like image 586
Shrejas Avatar asked Feb 07 '14 07:02

Shrejas


People also ask

What color space do iOS apps use?

For apps linked against the iOS 9 SDK and earlier, or running on iOS 9 and earlier, colors use one of two color spaces: These device color spaces correspond closely to the display characteristics of the sRGB color space. Component values within these color spaces are in the range 0.0 to 1.0.

How to choose the right UI design colors?

Different UI design colors signal various concepts to the senses. Ideally, you want to choose the right one at the right time and in the right pattern. They must be aimed toward the correct users, and you should choose them to target the proper goals. The red refers to what we call warm colors.

How do you define a color in iOS?

If you are working with RGB colors you usually define your color the same way, except that in iOS the values are between 0 and 1, but that's just a different representation of the fraction of 255. So you can make a color with RGB codes using the same logic.

What are complementary UI color schemes?

Complementary UI Color Schemes: This is an option that is based on the interplay of complementing cool and warm colors. They work well when they exist across from each other on color wheels. For this technique, some handy tools exist like Check My Color, Coolors.co, and Paletton.


5 Answers

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");
}
like image 95
trojanfoe Avatar answered Oct 18 '22 00:10

trojanfoe


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)
}
like image 34
the_critic Avatar answered Oct 18 '22 01:10

the_critic


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
}
like image 22
Mani Avatar answered Oct 18 '22 01:10

Mani


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.

like image 2
Larme Avatar answered Oct 18 '22 01:10

Larme


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
like image 1
Burhanuddin Sunelwala Avatar answered Oct 18 '22 00:10

Burhanuddin Sunelwala