1

私は実際にビューに線を引こうとしています。すべての描画の前にコンテキストをクリアしないようにするために、描画するために独自のコンテキストを作成する必要があることを理解しました。

コンテキストを作成するこの方法を見つけました:

CGContextRef MyCreateBitmapContext (int pixelsWide,
                                int pixelsHigh)
{
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;

    bitmapBytesPerRow   = (pixelsWide * 4);
    bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

    colorSpace = CGColorSpaceCreateDeviceRGB();
    bitmapData = calloc( bitmapByteCount, sizeof(int) );
    if (bitmapData == NULL)
    {
        fprintf (stderr, "Memory not allocated!");
        return NULL;
    }
    context = CGBitmapContextCreate (bitmapData,
                                     pixelsWide,
                                     pixelsHigh,
                                     8,      // bits per component
                                     bitmapBytesPerRow,
                                     colorSpace,
                                     kCGImageAlphaPremultipliedLast);
    if (context== NULL)
    {
        free (bitmapData);
        fprintf (stderr, "Context not created!");
        return NULL;
    }
    CGColorSpaceRelease( colorSpace );

    return context;
}

しかし、私の質問は次のとおりです。ビューを毎回きれいにしないために、このコンテキストをどのように使用できますか?

EDIT (@Peter Hoseyの回答後)

私は次のようなことをしようとします:

- (void)drawRect:(CGRect)rect {
    // Creation of the custom context
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGImageRef cgImage = CGBitmapContextCreateImage(context);
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), cgImage);
    CGImageRelease(cgImage);
    if (isAuthorizeDrawing) {
         [self drawInContext:context andRect:rect]; // Method which draw all the lines sent by the server
         isAuthorizeDrawing = NO;
    }

    // Draw the line
    [currentDrawing stroke];
}

また、UIView の clearsContextBeforeDrawing を NO に設定しました。

ズームすると (正しくスケーリングされたすべての線を再描画するために isAuthorizeDrawing が YES に設定されます)、線は消えませんが、新しい線を描画しようとすると (各 setNeedsDisplay 呼び出しですべてを再描画しないように isAuthorizeDrawing が NO に設定されます) )、すべての線が消えて、描画が非常に遅くなります.. :/

私は何か間違っていますか?

編集2

ここに私の描画方法があります:

-(void)drawInContext:(CGContextRef)context {
    for (int i = 0; i < self.drawings.count; ++i) {
        Drawing* drawing = [self.drawings objectAtIndex:i];

        CGContextSetStrokeColorWithColor(context, drawing.colorTrait.CGColor);
        CGContextSetLineWidth(context, 1.0);

        CGContextMoveToPoint(context, [[drawing.points objectAtIndex:0] CGPointValue].x * self.zoomScale, [[drawing.points objectAtIndex:] CGPointValue].y * self.zoomScale);

        for (int i = 1; i < drawing.points.count; i++) {
            CGContextAddLineToPoint(context, [[drawing.points objectAtIndex:i] CGPointValue].x * self.zoomScale, [[drawing.points objectAtIndex:i] CGPointValue].y * self.zoomScale);
        }

        CGContextStrokePath(context);
    }
}

-(void)drawRect:(CGRect)rect {
    if (isRedrawing) {
        [self drawInContext:UIGraphicsGetCurrentContext()];
        isRedrawing = NO;
    }

    [[UIColor redColor] set];
    [currentPath stroke];
}
4

1 に答える 1

4

あなたの文脈はあなたのためにあなたのすべての図面を保持します。

ビューによって提供されるコンテキスト(つまり、内drawRect:)に描画している場合、ビューは毎回新しいコンテキストを作成しているか、Etch-a-Sketchを振るなど、コンテキストのコンテンツを消去しています。いずれにせよ、(少なくとも事実上)何も描かれていないコンテキストを取得しています。

コンテキストに描画しいるとき、使用の合間に消去するために何もしていないと仮定すると、コンテキストに描画するものはすべて積み重なってしまいます。

これの影響の1つは、描画セッション間でこれらのパラメータをリセットするものがないため、現在の変換行列やクリッピングパスなどの描画状態に注意する必要があることです。何をしているのかにもよりますが、それは役に立つかもしれませんが、どちらにしても、それを認識し、それに応じて計画する必要があります。

おそらく、これまでに描いたものを時々(つまり、いつdrawRect:発生するか)ユーザーに見せたいと思うでしょう。これを行うには、ビットマップコンテキストにそのコンテンツの画像を作成し、その画像を現在の(UIKit提供の)コンテキスト描画するように依頼します。

または、描画の前に自分自身をクリアしないようにビューに指示し、独自のビットマップコンテキストを管理する必要はありません。

于 2012-12-24T18:33:24.463 に答える