3

I am making a simple iPhone drawing program as a personal side-project.

I capture touches event in a subclassed UIView and render the actual stuff to a seperate CGLayer. After each render, I call [self setNeedsLayout] and in the drawRect: method I draw the CGLayer to the screen context.

This all works great and performs decently for drawing rectangles. However, I just want a simple "freehand" mode like a lot of other iPhone applications have.

The way I thought to do this was to create a CGMutablePath, and simply:

CGMutablePathRef path;
-(void)touchBegan {
    path = CGMutablePathCreate();
}
-(void)touchMoved {
    CGPathMoveToPoint(path,NULL,x,y);
    CGPathAddLineToPoint(path,NULL,x,y);

}
-(void)drawRect:(CGContextRef)context {
      CGContextBeginPath(context);
      CGContextAddPath(context,path);
      CGContextStrokePath(context);
}

However, after drawing for more than 1 second, performance degrades miserably.

I would just draw each line into the off-screen CGLayer, if it were not for variable opacity! The less-than-100% opacity causes dots to be left on the screen connecting the lines. I have looked at CGContextSetBlendingMode() but alas I cannot find an answer.

Can anyone point me in the right direction? Other iPhone apps are able to do this with very good efficiency.

4

2 に答える 2

1

SanHoloが言ったこと-さらに、ポイントの追加を抑制したい場合があるため、たとえば、10ミリ秒ごとに新しいポイントを追加するだけです(間隔で遊ぶ必要があります)。簡単なタイマーでそれを行うことができます。

また、それ自体を再描画する必要があることをビューにどのように指示していますか? それも調整したいかもしれません-そして、それはポイントキャプチャよりも長い間隔になる可能性があります(たとえば、ポイントをキャプチャするのは10ミリ秒ごと、再描画の頻度は200ミリ秒未満です-ここでも、数値で遊ぶ必要があります) .

どちらの場合も、間隔より長く何も起こらない場合は、最後のポイントがキャプチャされるか、再描画が要求されることを確認する必要があります。そこでタイマーの出番です。

于 2009-11-11T13:45:44.597 に答える
1

問題はCGStrokePath()、現在の変更可能なパスが閉じられて描画され、指を動かすと新しいパスが作成されることです。したがって、おそらく、ワンタッチの「セッション」に多くのパスが作成されることになります。少なくとも、疑似コードはそうしているようです。

タッチが開始したときに新しい可変パスを開始しようとすることができますCGAddLineToPoint()。タッチが移動したときに使用し、タッチが終了したときにパスを終了します (疑似コードが示すように)。ただし、描画メソッドでは、現在の可変パスのコピーを描画し、実際の可変パスはタッチが終了するまで引き延ばされているため、タッチ セッション全体で 1 つのパスしか取得できません。タッチが終了したら、パスを永続的に追加できます。たとえば、すべてのパスを配列に入れて、draw メソッドで反復処理できます。

于 2009-11-11T12:42:00.620 に答える