読者です 読者をやめる 読者になる 読者になる

甘いものが好きです

iOS App開発時に感じた疑問や課題、その他の雑感などを書いていきます。

Popover内のNavigation Controllerのpush/popに応じてPopoverのサイズを調整する

iPad AppでPopover内にNavigationベースのViewを表示するときの話。*1

Popoverのサイズが元に戻らないことがある

Navigation ControllerのRoot Viewのサイズが、その1つ下の階層のView(ここでは「Second View」と呼ぶ)のサイズよりも小さい場合、Second Viewが表示された時点でPopoverのサイズがSecond Viewのサイズに合わせて自動的に変化する(大きくなる)。しかし、Second ViewからRoot Viewに戻るときには、PopoverのサイズはSecond View表示時に大きくなったままであり、Root Viewのサイズに合わせて小さくなることはない。そのため、Root Viewに戻ったときのPopoverの中には無駄なスペースが多くなり、そのPopoverにより隠れてしまう部分の面積が大きくなってしまう。

ユーザ体験に配慮するならば、Root Viewに戻った時点でPopoverのサイズがRoot Viewに合わせて小さくなるべきだ。調査した結果、そのためにはいくつかの処理を追加する必要があることがわかったので、本記事に整理する。

手動でPopoverのサイズを変更する

自動的にPopoverのサイズが変化しないのであれば、手動でサイズ変更すればよい。UIViewControllerクラスのプロパティcontentSizeForViewInPopoverに適切なサイズを設定することにより、サイズ変更を行うことができる。さっそく、Root View ControllerのviewWillAppear:やviewDidAppear:の中でcontentSizeForViewInPopoverを設定してみよう。するとどうなるか。結論を言うと、サイズは指定したものと違うものになるか、全く変化しないかのどちらかだ。

Stack Overflowのこの記事によると、Root View ControllerのviewDidAppear:の中でcontentSizeForViewInPopoverに異なるサイズを2回設定することにより、2回目に設定したサイズがPopoverのサイズになるとのこと。コードで表すと次のようになる。

- (void)forcePopoverSize {
    CGSize currentSetSizeForPopover = CGSizeMake(320.0f, 480.0f); // 最終的に設定したいサイズ
    CGSize fakeMomentarySize = CGSizeMake(currentSetSizeForPopover.width - 1.0f, currentSetSizeForPopover.height - 1.0f);
    self.contentSizeForViewInPopover = fakeMomentarySize;
    self.contentSizeForViewInPopover = currentSetSizeForPopover;
}

- (void)viewDidAppear:(BOOL)animated {
    [self forcePopoverSize];
    [super viewDidAppear:animated];
}

*1:本記事の内容は、特に断りがない限りiOS SDK 4.3で確認しているものとする。