setNeedsDisplayInRect: での矩形の指定方法
- 2012年11月30日
- iOSアプリ開発
安定動作のためのsetNeedsDisplayInRect:
ピンクのUIView Yの中のdrawRect:で線を描いたりしているのですが、ズームインしたときにはこのYを大きく拡大したりしています。
そのためsetNeedsDisplayでこのY全体を再描画していると、その瞬間にだけものすごい量のメモリを使ってアプリが落ちてしまったりしていました。
そこで、少なくとも再描画が必要な範囲(例の青の部分)というのを特定して、その範囲だけを再描画することにしました。
setNeedsDisplayInRect:の再描画範囲がおかしい?
しかし、ちゃんと再描画が必要な範囲を計算して、setNeedsDisplayInRect:に渡しているはずなのに、再描画される範囲がどう見てもおかしく正常動作しませんでした。
NSLogで渡している矩形を書き出したりして何度もチェックしたのですが、渡している矩形の範囲は数字上は正しいはずなのに、画面では再描画範囲が指定した範囲よりも右下にずれているような。。。?
値をいろいろと変えたり、あちこちにデバッグライトを入れてチェックしたりすること数時間、原因が分かりました。
原因は
setNeedsDisplayInRect:には、それを呼び出しているレシーバーを基準にした座標系のCGRectを渡す必要があったのでした。
上の例だと、私はUIView Xの座標系で計算したCGRectを渡しちゃっていたので、レシーバーであるUIView Yのoriginの分だけ右下にずれた範囲が再描画対象になっていたのでした。
UIView Yの中の青の部分だけを再描画させるためには、
CGRect r1 = CGRectMake(120,150,180,190); /* これじゃダメ */
CGRect r2 = CGRectMake(60,70,180,190); /* こちらが正解 */
r1だとダメで、r2をsetNeedsDisplayInRect:に渡してやる必要があります。
図形の変化に合わせてピンクのUIView Yのframeも変化していたので原因特定にすごく時間がかかりました。
実は、もちろんマニュアルにも書いてある。(なので誰も悩まないのでgoogleで検索しても解決できなかった・・・)
invalidRect
The rectangular region of the receiver to mark as invalid; it should be specified in the coordinate system of the receiver.
読んだはずなんだけどなぁ。
あんまりピンと来なくてスルーしてしまったのか?
教訓:マニュアルはちゃんと読もう!