私が今まで理解していた限り、drawRect:にUIViewの何かを描画するたびに、全体のコンテキストが消去されてから再描画されます。UIView(iPhone)で段階的に描画する
は、だから私は一連のドットを描画するために、このような何かをする必要があります:
方法A:意味すべての呼び出し
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, self.bounds, maskRef); //draw the mask
CGContextClipToMask(context, self.bounds, maskRef); //respect alpha mask
CGContextSetBlendMode(context, kCGBlendModeColorBurn); //set blending mode
for (Drop *drop in myPoints) {
CGContextAddEllipseInRect(context, CGRectMake(drop.point.x - drop.size/2, drop.point.y - drop.size/2, drop.size, drop.size));
}
CGContextSetRGBFillColor(context, 0.5, 0.0, 0.0, 0.8);
CGContextFillPath(context);
}
上のすべてを描く、私はすべての私のドットを格納する必要が(それは問題ありません)、新しいものを追加するたびに、それらを1つ1つずつ再描画します。残念ながら、これは私のひどいパフォーマンスをもたらし、もっと効率的にこれを行う他の方法があると確信しています。
編集:MrMageのコードを使用して、私は残念ながら遅くて色の混合がうまくいかず、次のことを行いました。私が試すことができる他の方法は?
方法B:保存前のはUIImageに描くだけ
- (void)drawRect:(CGRect)rect
{
//draw on top of the previous stuff
UIGraphicsBeginImageContext(self.frame.size);
CGContextRef ctx = UIGraphicsGetCurrentContext(); // ctx is now the image's context
[cachedImage drawAtPoint:CGPointZero];
if ([myPoints count] > 0)
{
Drop *drop = [myPoints objectAtIndex:[myPoints count]-1];
CGContextClipToMask(ctx, self.bounds, maskRef); //respect alpha mask
CGContextAddEllipseInRect(ctx, CGRectMake(drop.point.x - drop.dropSize/2, drop.point.y - drop.dropSize/2, drop.dropSize, drop.dropSize));
CGContextSetRGBFillColor(ctx, 0.5, 0.0, 0.0, 1.0);
CGContextFillPath(ctx);
}
[cachedImage release];
cachedImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();
//draw on the current context
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, self.bounds, maskRef); //draw the mask
CGContextSetBlendMode(context, kCGBlendModeColorBurn); //set blending mode
[cachedImage drawAtPoint:CGPointZero]; //draw the cached image
}
EDIT新しいものと、この画像を描画:私は方法の一つが、中にのみ再描画して以下に言及して結合されたすべての後 を新しいrect。結果は次のとおりです。 FAST METHOD:
- (void)addDotAt:(CGPoint)point
{
if ([myPoints count] < kMaxPoints) {
Drop *drop = [[[Drop alloc] init] autorelease];
drop.point = point;
[myPoints addObject:drop];
[self setNeedsDisplayInRect:CGRectMake(drop.point.x - drop.dropSize/2, drop.point.y - drop.dropSize/2, drop.dropSize, drop.dropSize)]; //redraw
}
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, self.bounds, maskRef); //draw the mask
CGContextClipToMask(context, self.bounds, maskRef); //respect alpha mask
CGContextSetBlendMode(context, kCGBlendModeColorBurn); //set blending mode
if ([myPoints count] > 0)
{
Drop *drop = [myPoints objectAtIndex:[myPoints count]-1];
CGPathAddEllipseInRect (dotsPath, NULL, CGRectMake(drop.point.x - drop.dropSize/2, drop.point.y - drop.dropSize/2, drop.dropSize, drop.dropSize));
}
CGContextAddPath(context, dotsPath);
CGContextSetRGBFillColor(context, 0.5, 0.0, 0.0, 1.0);
CGContextFillPath(context);
}
みんなありがとう!
"* view.clearsContextBeforeDrawing = NO; *"それは何をすべきドキュメントに記載しましたか?すべての図面はインクリメンタルでなければなりませんか?しかし、そうではありません。 – Dimitris
drawRect:実装が更新されたセクションのみを描画することを確認しない限り、描画はインクリメンタルではありません。 "更新されたセクション"(ダーティセクション)をマークする標準的な方法は、setNeedsDisplayInRect:を使用しています。 clearsContentBeforeDrawing = NOを設定して、コンテンツ全体をコンテントで埋めると、パフォーマンスのメリットは小さくなります。 –