オープンソースこねこね

Webプログラミングなどについてあれこれ。

UIPageViewControllerをUINavigationControllerにいれたらナビゲーションバー部分に潜り込まなくなった件

iOS8でUIPageViewControllerトランジションスタイルをUIPageViewControllerTransitionStyleScrollにしたときのみ発生する。。。マジなんなのこれ。。。しかも一度でも画面をタップすると、潜り込む(正常な)位置に移動するという。挙動が奇妙すぎてStack Overflowでも見つからないし。iOS8のバグを疑ってしまう。ヾ(`Д´)ノ"

f:id:kohkimakimoto:20141203064908g:plain

このサンプルはXcodePage-Based Applicationが作った雛形のプロジェクトを元に、RootViewControllerをNavigationControllerにいれる、のとUIPageViewControllerの初期化処理を以下のようにUIPageViewControllerTransitionStyleScrollを指定するように変えたもの。

self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

表示されるViewのframeなどを調べてみてもx=0,y=0となっていて変なところはない。それでViewの階層を見てみたらこんな感じになっている。 なんか下にズレてる。。。

f:id:kohkimakimoto:20141203065549p:plain

_UIQueuingScrollViewというViewの位置がy=-64.0という謎な状態になっていて、その子となるViewがその分だけ下にずれている。 しかもこれviewWillAppear:などのフェーズでは確認できず、viewDidAppear:まで到達して初めてこの状態になる。

というわけで以下のようなワークアラウンドを入れた。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)) {
        for (UIView *v in self.pageViewController.view.subviews){
            if ([v isKindOfClass:[UIScrollView class]]) {
                UIScrollView *scv = (UIScrollView *)v;
                CGPoint offset = scv.contentOffset;
                if (offset.y < 0) {
                    offset.y = 0;
                    scv.contentOffset = offset;
                }
            }
        }
    }
}

iOS8の場合、UIPageViewControllerUIScrollViewをとってきてマイナス値なら0に書き換えるということをやっています。これでなんとか対応できた。

追記

コメント欄でアドバイスをいただいて「UIPageViewControllerのAdjust Scroll View Insetsのチェックを外す」で対応できることがわかりました。