1. ホーム
  2. ios

[解決済み] iPhoneのポートレートでUISplitViewControllerを使用すると、マスターではなく詳細VCが表示される

2022-04-20 23:29:25

質問

Xcode 6でiOS 7以降をターゲットにしたユニバーサルストーリーボードを使用しています。私は UISplitViewController これは現在、iOS 8 を実行している iPhone でネイティブにサポートされており、Xcode は自動的に iOS 7 用にバックポートします。とてもうまくいっているのですが、iOS 8を搭載したiPhoneのポートレートでアプリを起動すると、最初にマスタービューコントローラーが表示されると思ったのに、スプリットビューの詳細ビューコントローラーが表示されることがあります。iOS 7でアプリを実行すると、正しくマスタービューコントローラーが表示されるので、これはiOS 8のバグだと信じていたのです。しかし、iOS 8はGMになり、まだこの現象が起きています。分割ビューコントローラを折りたたむ(画面にビューコントローラを1つだけ表示する)場合、分割ビューコントローラを表示すると、詳細ではなくマスタービューコントローラを表示するようにするには、どのように設定すればよいでしょうか。

Interface Builderでこのような分割ビューコントローラを作成しました。分割ビューコントローラは、タブバーコントローラの中の最初のビューコントローラです。マスターと詳細の両方のVCは、内部にテーブルビューコントローラを埋め込んだナビゲーションコントローラです。

どのように解決するのですか?

やれやれ、これは数日間頭痛の種で、どうすればいいのか分かりませんでした。 最悪だったのは、マスター・ディテールのテンプレートで新しいXcode iOSプロジェクトを作るとうまくいったことです。 幸いなことに、最終的にはその小さな事実が解決策を見出す方法となりました。

私が見つけたいくつかの投稿によると、解決策は、新しく実装された primaryViewControllerForCollapsingSplitViewController: メソッドを UISplitViewControllerDelegate . それを試してみたが、無駄だった。 Appleがマスター・ディテールのテンプレートでやっていることで、うまくいきそうなのは、新しい(この1つをすべて言うために深呼吸してください)実装です。 splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: デリゲートメソッド(これも UISplitViewControllerDelegate ). によると ドキュメント , このメソッドです。

プライマリビューコントローラを調整し、セカンダリビューコントローラを折りたたまれたインターフェイスに組み込むよう、デリゲートに依頼します。

具体的な内容は、そのメソッドのディスカッションの部分を必ず読んでください。

アップルの対応方法は

- (BOOL)splitViewController:(UISplitViewController *)splitViewController
collapseSecondaryViewController:(UIViewController *)secondaryViewController
  ontoPrimaryViewController:(UIViewController *)primaryViewController {

    if ([secondaryViewController isKindOfClass:[UINavigationController class]]
        && [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]]
        && ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) {

        // Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
        return YES;

    } else {

        return NO;

    }
}

この実装では、基本的に以下のことを行います。

  1. もし secondaryViewController は私たちが期待しているものです(a UINavigationController を表示し、私たちが期待しているもの(a)を表示しています。 DetailViewController -- あなたのビューコントローラ) が、モデルを持たない ( detailItem ) の場合、" Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded. "。
  2. それ以外の場合は、" を返します。 NO を使用して、分割ビューコントローラがセカンダリビューコントローラのコンテンツを折りたたまれたインターフェイスに組み込んでみるようにします"。

結果は、iPhoneのポートレート(ポートレートで起動するか、ポートレートに回転する--より正確にはコンパクトなサイズクラス)の場合、次のようになります。

  1. 正しく表示されている場合
    • を表示し、モデルを持つ場合は、詳細ビューコントローラを表示します。
    • が、モデルを持っていない場合、マスタービューコントローラを表示します。
  2. ビューが正しくない場合
    • マスタービューコントローラーを表示する

泥のように澄んでいる。