アプリであそぼう。こどもも、おとなも。

iPhone4などのRetinaディスプレイでsetNeedDisplayを使うと重くなる場合の対処



お絵描きアプリで線などを描画するとき、通常setNeedDisplayを使うと思います。

iPhone3GやiPhone3GSなどではスラスラ描画できるのですが、Retinaディスプレイのデバイスで試すと、やたら描画が遅れて線がカクカクしてしまうことがあります。

これはsetNeedDisplayで画面全体を再読み込みしていることが原因です。つまり、touchesMovedで呼び出している場合、指で画面をドラッグするたびに画面全体が何度も何度も読み込まれるので、処理が追いつかなくなりわけです。

こういう場合はsetNeedsDisplayInRectを使います。これは画面のうち必要な部分だけを再読み込みするもので、読み込まれる部分が少ないのでその分処理が早くなります。

使い方はこんな感じ。

[self setNeedsDisplayInRect:CGRectMake(読み込む部分の開始位置x軸, 読み込む部分の開始位置y軸, 読み込むサイズx軸, 読み込むサイズy軸)];

最初の2つで読み込みの開始位置を指定し、後の2つで読みこむサイズを指定します。

1点だけ注意が必要なのが、読み込みの開始位置は線の半径分をマイナスしなくてはいけません。
つまり、線は指でさわった点を中心点としてそこから半径のサイズに描画するため、読み込みの開始位置も半径分マイナスするわけです。

たとえば、CGContextSetLineWidthで線の太さを200にした場合、開始位置は半径の分の100を引いた数値を指定します。
[self setNeedsDisplayInRect:CGRectMake(currentPoint.x - 100, currentPoint.y - 100, 200, 200)];

これで処理が少し早くなります。ただ、あまりにも読み込むサイズが小さいと素早くかつ広い範囲で線を描画したときに線が読み込む範囲を超えてしまい、うまく描画できなくなるのでそこは数値を変えてチェックを繰り返して試してみてください。