0

我正在创建一个由自定义滑块类型控件控制的简单颜色选择器。

我将一个浮点值从我的滑块传递到 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 个像素。我应该将其限制为有限数量的颜色/值,而不是仅仅传入任意浮点数吗?同样,在模拟器中运行良好,似乎只是一个性能问题。

4

2 回答 2

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];

    }

}

我滚动自己的滑块的原因是我可以跳转到新值,而不必完美地捕捉小滑块控件,我发现它的交互不是很好。

于 2009-04-27T02:32:06.303 回答
1

在 iPhone 上绘图是双缓冲的。如果你开始闪烁,那是因为你在画一个东西然后另一个 - 这不是因为速度问题。

我猜你正在犯以下错误之一:

  • 更新你的颜色值和绘制你的颜色方块不同步(所以当你drawInRect时颜色设置不正确:)
  • 未能正确初始化/计算您的颜色(因此您显示无效颜色)
  • 当你不应该擦除或重绘你的矩形

另一件事要检查... Cocoa 中的颜色是从 0 到 1 的浮点数。将整数值设置为 0 到 255(在 web 或 Windows 上使用)将导致严重的奇怪问题。如果您的颜色计算超过 0 到 255,则在设置 UIColor 之前除以 255.0。

于 2009-04-15T12:05:57.100 回答