0

カスタム スライダー タイプ コントロールによって制御される単純なカラー ピッカーを作成しています。

スライダーから UIColor コンストラクター メソッドに float 値を渡し、値が変化すると CALayer の背景色を更新します。

シミュレーターでは非常にスムーズに動作しますが、デバイスで実行するとちらつきが多くなります。

これは、GPU に負担がかかりすぎているためですか? 妙にブルーの中を移動するときは最悪です。また、アルファ値と明るさを変更すると、彩度と色相を変更するよりもちらつきが大きくなります。

スライダーの値が変化するときに、任意の float 値を渡すべきではありませんか? そうでない場合、最適化のためにこれをより少ない色に制限するにはどうすればよいですか?

CALayer の backgroundColor プロパティの暗黙的なアニメーションを無効にすることを考えましたが、これを行う方法がわかりません。

UIColor の変更を最適化するためのトリックはありますか?

アップデート

drawRect: または drawInRect: を使用していません。

CALayer の backgroundColor プロパティを変更しているだけです。touchesMoved: が呼び出されるたびに、位置を取得し、0.0 から 1.0 の float 値を作成して、値が変更されたというメッセージをデリゲートに渡し、-(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;  

}

最初は、タッチ インターフェースの不正確さによる値の飛び越しだと思いました。スムージング機能は役に立ちましたが、場所が 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での描画はダブルバッファリングされます。ちらつきが発生している場合、それは1つのものを描画しているためであり、次に別のものを描画しているためです。速度の問題が原因ではありません。

次のいずれかの間違いを犯していると思います。

  • 色の値を更新し、色の正方形を同期して描画しません(したがって、drawInRect:)のときに色が正しく設定されません。
  • 色を正しく初期化/計算できない(無効な色を表示している)
  • すべきでないときに長方形を消去または再描画する

チェックするもう1つのこと...Cocoaの色は0から1までの浮動小数点数です。0から255までの整数値を設定すると(WebまたはWindowsで使用されるように)、深刻な奇妙な問題が発生します。色の計算が0から255を超える場合は、UIColorを設定する前に255.0で割ります。

于 2009-04-15T12:05:57.100 に答える