我正在创建一个由自定义滑块类型控件控制的简单颜色选择器。
我将滑块中的浮点值传递给UIColor构造函数方法,并在值更改时更新CALayer的背景颜色。
它在模拟器中运行非常顺畅,但在设备上运行时会出现很多闪烁现象。
这只是因为它对GPU过度征税吗?通过蓝色移动是最糟糕的。并且改变alpha值和亮度闪烁比改变饱和度和色调更多。
当滑块值改变时,我不应该传递任意浮点值吗?如果没有,我怎么能将此限制为更少的颜色进行优化?
我想过为CALayer的backgroundColor属性禁用隐式动画,但我不知道该怎么做。
是否有任何优化UIColor更改的技巧。
更新
我没有使用drawRect:或drawInRect:
我只是更改了CALayer的backgroundColor属性。每次touchesMoved:调用我抓取位置,创建一个0.0到1.0的浮点值,并向我的委托传递值已更改的消息,并调用 - (void)updateCurrentColor方法。
以下是我的实施示例:
@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;
}
起初我认为由于触摸界面的不精确,它是跳跃值。平滑功能有所帮助,但它仍然会闪烁一些,尤其是alpha值,即使我的位置只改变1个像素。我应该将此约束为有限数量的颜色/值而不是仅仅传递任意浮点数吗?再次,在模拟器中运行很好,似乎只是一个性能问题。
答案 0 :(得分:2)
禁用隐式动画消除了闪烁。
我已经更新了颜色更改方法,以便在从touchesBegan:调用时可以为背景颜色设置动画,但在从touchesMoved调用时不会隐式动画:
- (void)updateCurrentColorAnimated:(BOOL)animated {
currentColor = [UIColor colorWithHue:hueSliderView.hueValue
saturation:colorView.saturationValue
brightness:colorView.brightnessValue
alpha:alphaSlider.alphaValue];
if (animated) {
colorLayer.backgroundColor = currentColor.CGColor;
}
if (!animated) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
colorLayer.backgroundColor = currentColor.CGColor;
[CATransaction commit];
}
}
我滚动自己的滑块的原因是我可以跳转到新值而不必完全捕捉小滑块控件,我发现它的相互作用不是很好。
答案 1 :(得分:1)
在iPhone上绘图是双缓冲的。如果你正在闪烁,那是因为你正在绘制一件事而另一件事 - 这不是因为速度问题。
我猜你会犯以下错误之一:
要检查的另一件事...... Cocoa中的颜色是从零到1的浮点数。设置0到255之间的整数值(在Web或Windows上使用)将导致严重的奇怪问题。 如果您的颜色计算超过0到255,则在设置UIColor之前除以255.0。