3

次のコードで UILabel をサブクラス化しましたが、これは正常に動作しますが、サブクラスを含むアニメーションは、通常の UILabels よりもはるかに遅く実行されます。Quartz が原因だと思いますが、少しスピードアップするためにできることはありますか?

- (void)drawTextInRect:(CGRect)rect
{
    CGSize shadowOffset = self.shadowOffset;
    UIColor *textColor = self.textColor;

    // Establish the Quartz 2D drawing destination:
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 1);
    CGContextSetLineJoin(context, kCGLineJoinRound);

    // Draw the label’s outline:
    CGContextSetTextDrawingMode(context, kCGTextStroke);
    self.textColor = [UIColor whiteColor];
    [super drawTextInRect:rect];

    // Draw the label:
    CGContextSetTextDrawingMode(context, kCGTextFill);
    self.textColor = [UIColor textColor];
    self.shadowOffset = CGSizeMake(0, 0);
    [super drawTextInRect:rect];

    self.shadowOffset = shadowOffset;
}
4

2 に答える 2

5

@MobileOverlordが言ったことは確かに当てはまります。特に、プロファイリングに関する部分はそうです。

shouldRasterize = YESを設定することは、包括的な解決策ではないことに注意します(その場合、Appleがデフォルトとして設定しなかったのはなぜですか?)。はい、スクロールパフォーマンスを向上させることができますが、キャッシュ内に大量の大きな画像が表示される可能性があるため、メモリ使用量を犠牲にしてそれを行うことができます。

また、作成時にオーバーヘッドが発生します。実際にラスタライズされたコピーを作成するためのオフスクリーンレンダリングパスが含まれていると思います(ただし、確認する必要があります)。レイヤーの使用方法によっては、実際にパフォーマンスが低下する可能性があります。

考慮すべき追加の要素は、ビューに透明性があるかどうかです。ビューが不透明であることをフレームワークに保証できる場合(setOpaque / isOpaqueを参照)、アルファチャネルなどに関連するすべての複雑さを考慮しないことで、レンダリングを最適化できます。同様の考慮事項がCALayerに適用されます。

最後に、あなたが示したコードのブロックの外側で、バッキングレイヤーに卑劣なことをしましたか(たとえば、影やコーナーの半径を設定します)?これは、アニメーションのパフォーマンスを停止する簡単な方法でもあります。

于 2012-02-07T01:13:20.553 に答える
3

ラベルの描画が終了したらshouldRasterize、そのレイヤーを呼び出すことができ、アニメーションが高速化されます。

shouldRasterize レイヤーが合成前にビットマップとしてレンダリングされるかどうかを示すブール値。アニメート可能

@property BOOL shouldRasterize 説明 このプロパティの値が YES の場合、レイヤーはローカル座標空間でビットマップとしてレンダリングされ、他のコンテンツと共に宛先に合成されます。フィルター プロパティの影の効果とすべてのフィルターはラスタライズされ、ビットマップに含まれます。ただし、レイヤーの現在の不透明度はラスタライズされていません。合成中にラスター化されたビットマップのスケーリングが必要な場合は、必要に応じて minificationFilter プロパティとmaggingFilter プロパティのフィルターが適用されます。

このプロパティの値が NO の場合、レイヤーは可能な限り宛先に直接合成されます。レイヤーは、合成モデルの特定の機能 (フィルターの組み込みなど) で必要な場合、合成前にラスター化される場合があります。

このプロパティのデフォルト値は NO です。

CALayer クラスリファレンスから

シミュレーターは、システムの処理能力とメモリーをフルに活用できるため、常にデバイスよりも優れた結果をもたらします。通常、この方法では欠陥のある結果が得られます。CoreAnimation と組み合わせて CoreGraphics 描画を行う場合は常に、実際のデバイスで結果をテストすることが重要です。

このために、Instruments Core Animation Tool でアプリを実行して、犯人を見つけようとすることができます。それに関する私のチュートリアルをチェックしてください。

インストゥルメント – コア アニメーションの最適化

于 2012-02-07T00:43:03.153 に答える