0

現在のプロジェクトでは、いくつかのUITableViewセルの背景として複雑な背景を描画する必要があります。この背景を描画するためのコードは、セルのdrawRect:メソッドで実行するとかなり長くCPUに負担がかかるため、全体的なパフォーマンスを向上させるために、CGLayerに1回だけレンダリングしてから、セルにブリットすることにしました。

CGLayerに背景を描画するために使用しているコード:

+ (CGLayerRef)standardCellBackgroundLayer
{
    static CGLayerRef standardCellBackgroundLayer;

    if(standardCellBackgroundLayer == NULL)
    {
        CGContextRef viewContext = UIGraphicsGetCurrentContext();
        CGRect rect = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, PLACES_DEFAULT_CELL_HEIGHT);

        standardCellBackgroundLayer = CGLayerCreateWithContext(viewContext, rect.size, NULL);
        CGContextRef context = CGLayerGetContext(standardCellBackgroundLayer);

        // Setup the paths
        CGRect rectForShadowPadding = CGRectInset(rect, (PLACES_DEFAULT_CELL_SHADOW_SIZE / 2) + PLACES_DEFAULT_CELL_SIDE_PADDING, (PLACES_DEFAULT_CELL_SHADOW_SIZE / 2));
        CGMutablePathRef path = createPathForRoundedRect(rectForShadowPadding, LIST_ITEM_CORNER_RADIUS);

        // Save the graphics context state
        CGContextSaveGState(context);

        // Draw shadow
        CGContextSetShadowWithColor(context, CGSizeMake(0, 0), PLACES_DEFAULT_CELL_SHADOW_SIZE, [Skin shadowColor]);
        CGContextAddPath(context, path);
        CGContextSetFillColorWithColor(context, [Skin whiteColor]);
        CGContextFillPath(context);

        // Clip for gradient
        CGContextAddPath(context, path);
        CGContextClip(context);

        // Draw gradient on clipped path
        CGPoint startPoint = rectForShadowPadding.origin;
        CGPoint endPoint = CGPointMake(rectForShadowPadding.origin.x, CGRectGetMaxY(rectForShadowPadding));
        CGContextDrawLinearGradient(context, [Skin listGradient], startPoint, endPoint, 0);

        // Restore the graphics state and release everything
        CGContextRestoreGState(context);
        CGPathRelease(path);
    }

    return standardCellBackgroundLayer;
}

レイヤーを現在のコンテキストにブリットするコード:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawLayerAtPoint(context, CGPointMake(0.0, 0.0), [Skin standardCellBackgroundLayer]);
}

これは実際にはかなりうまくいきますが、私が抱えている唯一の問題は、角が丸いことです(静的メソッドを確認してください)。画面にブリットしたときに非常にギザギザです。これは、描画コードが元の位置(drawRectメソッド内)にある場合には当てはまりませんでした。

このアンチエイリアスを取り戻すにはどうすればよいですか?

何らかの理由で、次の方法はアンチエイリアスに影響を与えません。

CGContextSetShouldAntialias(context, YES);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetAllowsAntialiasing(context, YES);

前もって感謝します!

4

2 に答える 2

1

UIGraphicsBeginImageContextWithOptionsスケールを使用してに設定するだけで、これを簡略化できます0.0

古い投稿を目覚めさせて申し訳ありませんが、他の誰かがそうするかもしれないので、私はそれに出くわしました。詳細については、UIGraphicsBeginImageContextWithOptions ドキュメントをご覧ください。

の値を指定すると0.0、倍率はデバイスのメイン画面の倍率に設定されます。

基本的には、Retinaディスプレイの場合、Retinaコンテキストが作成されることを意味します0.0。これにより、座標を指定してポイントとして扱うことができます。

于 2013-03-03T04:49:06.097 に答える
0

少し前に理解したので、私は自分の質問に答えるつもりです。網膜を意識したコンテキストを作成する必要があります。ギザギザは網膜デバイスにのみ現れました。

この動作に対抗するには、次のヘルパーメソッドを使用して網膜コンテキストを作成する必要があります。

// Begin a graphics context for retina or SD
void RetinaAwareUIGraphicsBeginImageContext(CGSize size) 
{
    static CGFloat scale = -1.0;

    if(scale < 0.0) 
    {   
        UIScreen *screen = [UIScreen mainScreen];

        if([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0)
        {    
            scale = [screen scale]; // Retina
        }
        else 
        {
            scale = 0.0; // SD
        }
    }

    if(scale > 0.0)
    {    
        UIGraphicsBeginImageContextWithOptions(size, NO, scale);   
    }
    else 
    {    
        UIGraphicsBeginImageContext(size);   
    }
}

次に、描画メソッドで、上記のメソッドを次のように呼び出します。

+ (CGLayerRef)standardCellBackgroundLayer
{
    static CGLayerRef standardCellBackgroundLayer;

    if(standardCellBackgroundLayer == NULL)
    {
        RetinaAwareUIGraphicsBeginImageContext(CGSizeMake(320.0, 480.0));
        CGRect rect = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, PLACES_DEFAULT_CELL_HEIGHT);

        ...
于 2012-01-06T13:28:00.937 に答える