I'm creating a simple color picker controlled by a custom slider type control.
I'm passing a float value from my slider to a UIColor constructor method and updating the background color of a CALayer as the value changes.
It runs really smooth in the simulator, but I get a lot of flickering when running on the device.
Is this just because it's over taxing the GPU? It's strangely the worst when moving through blue. And changing the alpha value and brightness flicker more than changing the saturation and hue.
Should I not pass arbitrary float values as the slider value changes? If not, how could I constrain this to less colors for optimization?
I thought of disabling implicit animations for the backgroundColor property of the CALayer, but I'm not sure how to do this.
Are there any tricks for optimizing UIColor changes.
Update
I'm not using drawRect: or drawInRect:
I'm just changing the backgroundColor property of a CALayer. Every time touchesMoved: is called I grab the location, create a 0.0 to 1.0 float value and pass a message to my delegate that the value has changed and call the -(void)updateCurrentColor method.
Here's an example of my implementation:
@implementation MyCustomSliderView
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
hueLocation = [[touches anyObject] locationInView:self];
//Smoothing
if ((hueLocation.x > previousHueLocation.x) && ((hueLocation.x - previousHueLocation.x) > 1.0) && (hueLocation.x - previousHueLocation.x) < 10.0) {
hueLocation.x = previousHueLocation.x + 1.0;
}
if ((hueLocation.x < previousHueLocation.x) && ((previousHueLocation.x - hueLocation.x) > 1.0) && (previousHueLocation.x - hueLocation.x) < 10.0) {
hueLocation.x = previousHueLocation.x - 1.0;
}
//Percentage of screen.
hueValue = hueLocation.x/self.bounds.size.width;
//Clip to 1.0 & 0.0
if (hueValue > 1.0) {
hueValue = 1.0;
}
if (hueValue < 0.0) {
hueValue = 0.0;
}
NSLog(@"Value is: %f", hueValue);
NSLog(@"Location %f", hueLocation.x);
previousHueLocation = hueLocation;
if([delegate respondsToSelector:@selector(updateCurrentColor)]) {
[delegate updateCurrentColor];
}
}
@implementation MyViewController
- (void)updateCurrentColor {
currentColor = [UIColor colorWithHue:hueSliderView.hueValue
saturation:saturationSliderView.saturationValue
brightness:brightnessSliderView.brightnessValue
alpha:alphaSliderView.alphaValue];
colorLayer.backgroundColor = currentColor.CGColor;
}
At first I thought that it was jumping values due to the imprecision of the touch interface. The smoothing function helped, but it still flickers some, especially with the alpha value, even when my location only changes by 1 pixel. Should I constrain this to a limited amount of colors/values instead of just passing in an arbitrary float? Again, runs great in the simulator, seems to be just a performance issue.