I am trying to draw a UIColor on the screen of a view-based app, and I am trying to do so using HSB. It is absolutely necessary for me to use HSB in this case. I can create a UIColor object with any S value from 0.0f to 0.75f, but past that the numerical changes have no effect on the actual saturation displayed. I need it to be 1.0f, but it is still using 0.75f. Any ideas on why it is doing that, and how I can make it work?
Because of how it works, + (UIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha
actually does not use HSBA values internally; it is simply a wrapper around the device RGB color space.
I think that under extreme cases there surely would be chances that a constant H/B/A + a .75–1 S yields colors that differ so slightly it became imperceptible, despite the color components being digitally tracked as very precise floats. As saturation drops, the number of “available” colors decreases (as the display could only show this many colors, dropping the saturation compresses the usable colors) and the chance of collision simply rises.
Given that your scenario uses H0-1, B1, A1 colors which nearly invalidates my assumption, I was curious and have made a test project; the colors however worked correctly. I’m on iOS 4 SDK GM, so maybe it’ll help if we know which SDK you’re working against.
After doing some experimentation, I've discovered what my issue was.
I was using a for loop to draw single-pixel lines across a view, each with a hue value greater than the previous one. I was doing this to create a color spectrum to be used for a color picker.
My issue arose because I was using CGContext paths, not rects, to do the drawing. Paths, by default, "straddle" the created path with pixels. Because I was setting the width to one, CoreGraphics was forced to average between pixels, creating a desaturated effect. Setting the width to two set the saturation correctly, but the gradient of the spectrum was no longer smooth.
My fix for this issue was to use rects instead of paths. They did not blend between pixels, and the saturation issue was fixed.