問題が発生するまで
参考にしたのは、こちら
http://qiita.com/malt/items/6468921e57a30594d037
この例に従って、Auto Layoutして、制約はクリアした。
viewForZoomingInScrollViewでスクロールすべきviewを返してあげれば、contentSizeも勝手に設定されるので、この辺はカット。
今回は表示すべきコンテンツをセンタリングしたかった。
contentOffsetでセンターに来るように設定したんだけど、
これをviewDidLayoutSubviewsで設定しても上に張り付いて、ピクリともしない。
仕方がないので、これを挟み込んだ。
(この辺からがダメな道)
dispatch_async(dispatch_get_main_queue(), ^{
...
}];
これで表示直後はセンタリングできるようになったんだけど、
ピンチイン、ピンチアウトで拡大縮小しようとしたら、変なことが起きた。
ピンチイン、ピンチアウトで指を離すと、これが呼ばれる
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView
withView:(UIView *)view
atScale:(CGFloat)scale
もちろん、拡大縮小中は、これらが呼ばれる。
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
scrollViewDidZoomが呼ばれた時に、contentOffsetを操作して、センタリングしてた。
ところがある一定の条件下で、scrollViewDidEndZoomingが呼び出された後に、scrollViewDidScrollが呼ばれることがあって、呼ばれた時に限って、contentOffsetが0になるようになってた。
(通常はscrollViewDidScrollが呼ばれた後にscrollViewDidEndZoomingで終わる)
だから、センタリングしたはずなのに、指を離すとコンテンツの位置が移動するという謎な現象に悩まされることになった。
どうやって解決したか
コンテンツとなるviewをセンタリングするようにAuto Layoutで設定したのち、
scrollViewDidZoomでコンテンツとなるviewに対して、centerを設定するようにした。
こんな感じ。
- (void)scrollViewDidZoom:(UIScrollView*)scrollView {
CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0);
CGFloat offsetY = MAX((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0);
self.contentView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
scrollView.contentSize.height * 0.5 + offsetY);
}
Auto Layoutで初期状態をセンタリングにしたから、viewDidLayoutSubviewsでは何もしなくても良くなった。
zoom後にoffsetが0になるような呼び出しもなくなった。(そもそもoffsetを自分で設定しなくなった。)
だいたいこれで終わりなんだけど、一つだけ引っかかるのが、訳あってコンテンツを初期状態ではUIViewContentModeScaleAspectFillで表示する(隠れる部分がある)のだけど、zoom処理をするまではなぜかスクロールが出来ない。(一旦ピンチインやピンチアウトをするとスクロールができるようになる)
この問題については、未解決。