1

I am storing an UIColor in NSUserDefaults, and the problem that I am having is that a simple equality check fails (for my tests) when retrieving the color back. Can somebody explain why this fails?

UIColor *color = [UIColor colorWithRed: 0.922 green: 0.404 blue: 0.024 alpha: 1];
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];

[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];

NSData *storedColorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *restoredColor = [NSKeyedUnarchiver unarchiveObjectWithData:storedColorData];

if ([color isEqual:restoredColor]) {
    NSLog(@"Same color");
} else {
    NSLog(@"Not the same color");
}

The result will be "Not the same color". Quick looking in the debugger will show that the colors are identical (the RGB and alpha values).

Popeye
  • 11,839
  • 9
  • 58
  • 91
José
  • 3,112
  • 1
  • 29
  • 42
  • isEqual: is a hash comparison. you need to compare the components of your color (red, green, blue, alpha) to determine if they are equal – Basheer_CAD Apr 09 '15 at 08:53

3 Answers3

3

If you declare your UIColor like this:

UIColor *color = [UIColor colorWithRed: (float)0.922 green: (float)0.404 blue: (float)0.024 alpha: (float)1];

both ways to compare colors will return YES in your example:

[color isEqual:restoredColor]
CGColorEqualToColor(color.CGColor, restoredColor.CGColor)

UPDATE: Category for comparison UIColor components

@interface UIColor (Compare)

- (BOOL)isEqualToColor:(UIColor *)otherColor;

@end

@implementation UIColor (Compare)

- (BOOL)isEqualToColor:(UIColor *)otherColor {
    const CGFloat *components = CGColorGetComponents(self.CGColor);
    float colorOne[4] = {components[0], components[1], components[2], components[3]};

    const CGFloat *otherComponents = CGColorGetComponents(otherColor.CGColor);
    float colorTwo[4] = {otherComponents[0], otherComponents[1], otherComponents[2], otherComponents[3]};

    return colorOne[0] == colorTwo[0] && colorOne[1] == colorTwo[1] && colorOne[2] == colorTwo[2] && colorOne[3] == colorTwo[3];
}

@end
anatoliy_v
  • 1,782
  • 15
  • 24
  • Thanks for all the answer, but accepting this since it explains what the underlying issue is + provides a nice solution. – José Apr 09 '15 at 10:59
  • 1
    Noticed that the numbers are doubles and that a simple f at the end of the numbers to make them floats is enough. The casting will not be needed. – José Apr 09 '15 at 11:48
1

Maybe this question can help you: https://stackoverflow.com/a/26284626/301661

You can try using CGColorEqualToColor(color.CGColor, restoredColor.CGColor) to compare colors.

Community
  • 1
  • 1
Fogh
  • 1,275
  • 1
  • 21
  • 29
1

If you NSLog both colors you will see that both colors are actually same!

NSLog(@"Color before: %@", color);
NSLog(@"Color after: %@", restoredColor);

// 2015-04-09 13:19:36.640 test[31149:6236981] Color before: UIDeviceRGBColorSpace 0.922 0.404 0.024 1
// 2015-04-09 13:19:36.641 test[31149:6236981] Color after: UIDeviceRGBColorSpace 0.922 0.404 0.024 1

so you need to compare each component of the UIColor explicitly i.e. red, green, blue and alpha.

Check out this answer!


Quite interestingly, if you log the hashes of these two colors, they too appear to be same

NSLog(@"Color Hash before: %lu", (unsigned long)[color hash]);
NSLog(@"Color Hash after: %lu", (unsigned long)[restoredColor hash]);

// 2015-04-09 13:59:06.097 test[31299:6252585] Color before: 137311944
// 2015-04-09 13:59:06.097 test[31299:6252585] Color after: 137311944

so you could compare the hashes and get it working.

if(color.hash == restoredColor.hash) {
   // ...
}

As said in the above accepted answer, the isEqualTo: doesn't work when you pass in double values. float values should be passed instead

UIColor *color = [UIColor colorWithRed:0.922f green:0.404f blue:0.024f alpha:1.0f];
Community
  • 1
  • 1
Burhanuddin Sunelwala
  • 5,318
  • 3
  • 25
  • 51
  • I thought about that doing that as well, and this might be the solution that I go with, but it would still be interesting to know what the equality check fails... – José Apr 09 '15 at 09:31