如何优化 iPhone 上的 UIColor?
Posted
技术标签:
【中文标题】如何优化 iPhone 上的 UIColor?【英文标题】:How do you optimize UIColor on the iPhone? 【发布时间】:2009-04-15 02:50:33 【问题描述】:我正在创建一个由自定义滑块类型控件控制的简单颜色选择器。
我将一个浮点值从我的滑块传递给 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 个像素。我应该将其限制为有限数量的颜色/值,而不是仅仅传入任意浮点数吗?同样,在模拟器中运行良好,似乎只是性能问题。
【问题讨论】:
描述你得到的效果。是否有可见的垂直/水平“条”变化可见?元素会暂时消失吗?您是否获得了可见但不需要的过渡颜色? 没有酒吧。当我更改值(色相、饱和度、亮度、alpha)时,颜色会忽明忽暗。如果我走得很慢,那就更好了,但有时还是会闪烁。我将 touchesMoved 方法调整为一次只移动一个像素,除非移动超过 15 个像素。这很有帮助。但仍然闪烁。 【参考方案1】:禁用隐式动画消除了闪烁。
我更新了颜色更改方法,以便在从 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];
我滚动自己的滑块的原因是我可以跳转到新的值,而不必完美地捕捉小滑块控件,我发现它的交互不是很好。
【讨论】:
【参考方案2】:iPhone 上的绘图是双缓冲的。如果你开始闪烁,那是因为你在画一个东西然后另一个 - 这不是因为速度问题。
我猜你犯了以下错误之一:
更新颜色值和绘制颜色方块不同步(因此在 drawInRect 时颜色设置不正确:) 未能正确初始化/计算颜色(因此您显示的颜色无效) 不该删除或重绘矩形要检查的另一件事... Cocoa 中的颜色是从 0 到 1 的浮点数。将整数值设置为 0 到 255(在 web 或 Windows 上使用)会导致严重的奇怪问题。 如果您的颜色计算超过 0 到 255,则在设置 UIColor 之前除以 255.0。
【讨论】:
在这种情况下“双缓冲”是什么意思? @Matt Gallagher,谢谢,刚刚更新了我的实施问题。 @erikprice “双缓冲”表示所有绘图都发生在屏幕外,然后在绘图完成后复制到屏幕上。这意味着擦除为白色,然后绘制黑色不会导致屏幕闪烁,因为从未显示白色状态。以上是关于如何优化 iPhone 上的 UIColor?的主要内容,如果未能解决你的问题,请参考以下文章