2

ユーザーがiPad/iPhoneの画面上で指を動かすと、点線を描くビューがあります。LastLocationとして保存されているポイントとCurrentLocationであるポイントの間に線を引きます。図面は画面上に永続的に表示されます。これは、touchMovedイベントが発生するたびに発生し、ペイントアプリケーションのように、人が指をドラッグした場所をトレースする点線を描画できるようになります。

タッチイベントが発生したときに次のように呼び出される関数があります。ビューには、drawImageと呼ばれるUIImageViewが含まれています。描画された線を永続化する手段としてUIImageViewを使用します。これは非常に遅いので、人々が通常ペイントアプリケーションを行う方法ではないことは明らかです。CGContextRef呼び出しを使用して永続的なペイントを行うためのより良い方法についての洞察をいただければ幸いです。

/* Enter bitmap graphics drawing context */
UIGraphicsBeginImageContext(frame.size);
/* Draw the previous frame back in to the bitmap graphics context */
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)]; //originally self.frame.size.width, self.frame.size.height)];       
/* Draw the new line */
CGContextRef ctx = UIGraphicsGetCurrentContext();
/* Set line draw color to green, rounded cap end and width of 5 */
CGContextSetLineDash(ctx, 0, dashPattern, 2);
CGContextSetStrokeColorWithColor(ctx, color);
CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
CGContextSetLineWidth(ctx, 5.0); // for size
/* Start the new path point */
CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y);
CGContextAddLineToPoint(ctx, Current.x, Current.y);
CGContextStrokePath(ctx);
/* Push the updated graphics back to the image */
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

'drawImage.image drawInRect'呼び出しは非常に遅く、本質的に画像全体を再描画します。

これを行うより速い方法はありますか?ブログのいくつかの場所でこのようなコードを描画するのを見たことがありますが、少し遅いです。このトピックに関するいくつかの考えを聞きたいです。

4

1 に答える 1

1

画像と線を手動で合成する必要はありません。画像を描画する別のUIImageViewの上に線を描画するビューがあります。システムに合成を行わせ、画像を描画します。

コードでは、線画ビューのdrawRect:メソッドの2つのdrawImage線の間で処理を実行します。

-(void) drawRect:(CGRect)dirty {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    /* Set line draw color to green, rounded cap end and width of 5 */
    CGContextSetLineDash(ctx, 0, dashPattern, 2);
    CGContextSetStrokeColorWithColor(ctx, color);
    CGContextSetLineCap(ctx, kCGLineCapRound); //kCGLineCapSquare, kCGLineCapButt, kCGLineCapRound
    CGContextSetLineWidth(ctx, 5.0); // for size
    /* Start the new path point */
    CGContextMoveToPoint(ctx, LastLocation.x, LastLocation.y);
    CGContextAddLineToPoint(ctx, Current.x, Current.y);
    CGContextStrokePath(ctx);
}

線の一方の端が移動したら、新しい点を保存し、線画ビューを表示する必要があるものとしてマークします。したがって、CurrentとLastLocationの両方が線画ビューのメンバーである必要があり、それぞれのsetterメソッドでsetNeedsDisplayを呼び出します。

線画ビューでclearsContextBeforeDrawingがYESで、opaqueがNOであることを確認してください。

于 2010-07-03T06:52:42.030 に答える