Reputation: 942
I have a UIButton consists of a title text and a single color background. The button is drawn on the white UIView, and the title text is black.
I want to randomly colorize the button's background every time I launch the app. Here is my implementation:
#define KEY_COLOR_R @"KEY_COLOR_R"
#define KEY_COLOR_G @"KEY_COLOR_G"
#define KEY_COLOR_B @"KEY_COLOR_B"
+ (void)setThemeColorRandomly {
//TODO: THEME COLOR NEEDS TO BE EASILY DISTINGUISHABLE WITH BLACK AND WHITE
float r = [Helper getRandomFloatBetweenLow:0 high:1];
float g = [Helper getRandomFloatBetweenLow:0 high:1];
float b = [Helper getRandomFloatBetweenLow:0 high:1];
[ModuleHelper cache_setFloat:r forKey:KEY_COLOR_R];
[ModuleHelper cache_setFloat:g forKey:KEY_COLOR_G];
[ModuleHelper cache_setFloat:b forKey:KEY_COLOR_B];
}
+ (UIColor *)themeColor {
float r = [ModuleHelper cache_floatForKey:KEY_COLOR_R];
float g = [ModuleHelper cache_floatForKey:KEY_COLOR_G];
float b = [ModuleHelper cache_floatForKey:KEY_COLOR_B];
return [UIColor colorWithRed:r green:g blue:b alpha:1];
}
the +setThemeColorRandomly
is called in -didFinishLaunching
And now I set the color:
[self.settingsButton setBackgroundColor:[CacheHelper themeColor]];
The problem is, I need to avoid the colors those are too light (mix with background) or too dark (mix with text). But I don't want to limit the diversity of colors, e.g. If I set the range to be 0.4-0.6 for all 3 colors, then I will miss red color, which is easily distinguishable with both white and black
EDIT:
The color I need to avoid is not just complete black and white. I need to avoid all the colors that are barely distinguishable.
The critical part is "distinguishable". for example, a very very light blue background is a bad choice.
Upvotes: 0
Views: 99
Reputation: 2842
I'd suggest using a hsb color model, this way you have full control over the brightness of your color:
//set your color randomly
CGFloat hue = [Helper getRandomFloatBetweenLow:0 high:1];
//you may play around with the saturation to get more colors as well
CGFloat saturation = 1;
//adjust your desired min max values
CGFloat brightness = [Helper getRandomFloatBetweenLow:0.3 high:0.7];
return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
Upvotes: 2
Reputation: 17687
See my example:
float r,g,b;
do {
r = [Helper getRandomFloatBetweenLow:0 high:1];
g = [Helper getRandomFloatBetweenLow:0 high:1];
b = [Helper getRandomFloatBetweenLow:0 high:1];
} while(r == 0 && g == 0 && b == 0);
in this case r g
and b
are recalculated if are all 0
(i.e. black color).
If instead on of them is different from 0, is ok.
You can extend the example for all 1
as well (white color).
In your case you can simply avoid the whit background on the button, and then all equal couple of color:
float r,g,b, r1,g1,b1;
//Calculate the background different from white
do {
r = [Helper getRandomFloatBetweenLow:0 high:1];
g = [Helper getRandomFloatBetweenLow:0 high:1];
b = [Helper getRandomFloatBetweenLow:0 high:1];
} while(r == 1 && g == 1 && b == 1);
//Calculate the text color different from the background
do {
r1 = [Helper getRandomFloatBetweenLow:0 high:1];
g1 = [Helper getRandomFloatBetweenLow:0 high:1];
b1 = [Helper getRandomFloatBetweenLow:0 high:1];
} while(r1 == r && g1 == g && b1 == b);
Or if you want use a range of tonality to be sure that the 2 color are enough different, you can use for example this last while:
} while(ABS(r1-r) > 0.3 && ABS(g1-g) > 0.3 && ABS(b1-b) > 0.3);
this is the function, you can choose your preference and tolerance.
Here the result:
Upvotes: 1