viewForZoomingInScrollViewの中で zoomScale を参照すると危険


UIScrollViewをピンチイン、ピンチアウトでズームイン、ズームアウトできるようにしました。

ここまでは apple Developer Library(日本語) iOS Scroll View プログラミングガイドの23ページあたりに書かれている通りにやるとすんなり動きました。

その後、ズーム前後でズームの倍率がどれくらい変わったかを知る必要があったので、
viewForZoomingInScrollViewの中で現在のズーム率を取得して、scrollViewDidEndZoomingの引数のscaleと比較してズーム倍率の変化を求めようと考えました。

しかし、viewForZoomingInScrollViewの中で、

beforeScale = [scrollView zoomScale];

などと現在の倍率を調べようとすると無限ループに陥ります。。。

NSLog(@"scale: %f",[scrollView zoomScale]);

なんてのもダメ。
これやっちゃうと固まってしまってしばらく処理を受け付けなくなってしまいました。

うーん、どうやらzoomScaleの値を取得する際にviewForZoomingInScrollViewが呼び出されているようなのです。

こちらにも同じ症状でお悩みの方が。
iphone – UIScrollView bug? float foo = scrollview.zoomScale crashes the app – Stack Overflow

結局scrollViewWillBeginZoomingの中でズーム前のズーム倍率を取得することにしました。
こちらのメソッドは内部でzoomScaleを参照しても大丈夫でした。

英語のヘルプ読んでもviewForZoomingInScrollViewとscrollViewWillBeginZoomingの違いはよく分かりませんでしたが、
使ってみた感じだと前者は、実際にズームされなくても2本指でタッチしたら呼ばれる、
後者は2本指でタッチした後で指を動かして実際にviewの大きさが変わり始めたら呼ばれる
ような感じかな。
viewForZoomingInScrollViewが呼ばれてもscrollViewDidEndZoomingが呼ばれないことは多々あって少し困っていたけど、scrollViewWillBeginZoomingが呼ばれた後は今のところ必ずscrollViewDidEndZoomingが呼ばれてて少し幸せになれました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です