18

私の元の質問:

私は単純な描画アプリケーションを作成しており、既存の以前に描画されたコンテンツをdrawRect. 完全に置き換えずに、既存のコンテンツの上に描画する適切な方法は何ですか?

ここや他の場所で受け取った回答に基づいて、これが取引です.

  1. drawRect が呼び出される たびに四角形全体を再描画する準備をしておく必要があります。

  2. 次の操作を行っても、内容が消去されるのを防ぐことはできません。

    [self setClearsContextBeforeDrawing: NO];

    これは、とにかく領域全体を再描画する必要がある可能性が高いため、ビューを事前にクリアしても意味がないというグラフィック エンジンへのヒントにすぎません。ビューが自動的に消去されるのを防ぐことができますが、それに依存することはできません

  3. 消去せずにビューの上に描画するには、オフスクリーン ビットマップ コンテキスト (システムによってクリアされることはありません) に対して描画を行います。次に、drawRectこのオフスクリーン バッファからビューにコピーします。

例:

- (id) initWithCoder: (NSCoder*) coder {    
     if (self = [super initWithCoder: coder]) {
         self.backgroundColor = [UIColor clearColor];
         CGSize size = self.frame.size;
         drawingContext = [self createDrawingBufferContext: size];
     }

     return self;
 }

- (CGContextRef) createOffscreenContext: (CGSize) size  {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, size.width*4, colorSpace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colorSpace);

    CGContextTranslateCTM(context, 0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    return context;
}


- (void)drawRect:(CGRect) rect {    
    UIGraphicsPushContext(drawingContext);
    CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext); 
    UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage];
    UIGraphicsPopContext();
    CGImageRelease(cgImage);
    [uiImage drawInRect: rect];
    [uiImage release];
 }

TODOdrawRect : (通常は小さい) 変更された四角形領域のみがコピーに使用されるように、誰でも最適化できますか?

4

4 に答える 4

5

オフスクリーン イメージにすべてを描画し、画面を描画するときにこのイメージを表示することはかなり一般的です。次を読むことができます:ビットマップ グラフィックス コンテキストの作成

于 2009-05-14T20:46:11.790 に答える
1

drawRectの最適化について

これを試して:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext);
    CGContextClipToRect(context, rect);
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), cgImage);
    CGImageRelease(cgImage);
}

その後、コード内の次の行もコメントする必要があります。

//CGContextTranslateCTM(context, 0, size.height);
//CGContextScaleCTM(context, 1.0, -1.0);

また、それが最適な方法であることを確認するために別の質問を作成しました。

于 2010-06-14T22:58:35.640 に答える
0

これは私が使っていたよりも良い方法のようです。つまり、touchsイベントで、更新されようとしているビューのコピーを作成します。次に、drawRectでその画像を取得してビューに描画し、同時に他のビューを変更します。

しかし、これは非効率的なようですが、私がそれを行う方法を理解する唯一の方法です。

于 2009-11-14T20:38:14.110 に答える
0

これにより、 drawRect が完了する前にビューが消去されるのを防ぎます。

[self.layer setNeedsDisplay];

また、drawRect メソッドですべての描画を行う方がよいと思います (そうしない正当な理由がない限り)。オフスクリーンで描画して転送すると、単純にすべてを 1 回描画するよりも時間がかかり、複雑さが増します。

于 2012-07-12T09:42:21.367 に答える