36

私は複雑なiPadビューを持っており、いくつかのビューコントローラーを使用して管理しています。以前(iOS6 / Xcode 4.5より前)は、ビューコントローラーをコードで割り当て、マスタービューへのリンクを介してさまざまなビューをそれらに接続することでこれを行いました。

私がやりたいのは、新しいUIContainerViewコンテナビューを使用して、ストーリーボードファイルにビューコントローラを埋め込むことです。組み込みViewControllerからMasterControllerへのIBOutletリンクを作成できないようです。

これを行うことは可能ですか?または、コード内のタグなどを介して組み込みコントローラーを取得するには?

この質問は、特にコンテナビューの使用に関するものです

4

5 に答える 5

71

場合によっては、を使用して組み込みコントローラーをキャプチャすることもできます-prepareForSegue:sender:

たとえば、にUINavigationController埋め込みがある場合、ストーリーボードCustomContainerViewControllerに埋め込みセグエに名前を付けて、経由embedContentStackでキャプチャできます。CustomContainerViewController

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"embedContentStack"]) {
        // can't assign the view controller from an embed segue via the storyboard, so capture here
        _contentStack = (UINavigationController *)segue.destinationViewController;
    }
}
于 2012-12-11T19:34:03.217 に答える
22

「組み込みコントローラーを取得する」とはどういう意味かわかりません。コントローラーを使用する場合は、UIStoryboardメソッドのinstantiateViewControllerWithIdentifier:を使用し、IBでコントローラーに指定した識別子を使用します。また、performSegueWithIdentifier:sender:メソッドを使用することもできます(これにより、ビューコントローラーもインスタンス化されます)。Appleドキュメントの「アプリでのViewControllerの使用」セクションを確認する必要があります。また、子ビューコントローラーがコンテナーコントローラーと同時にインスタンス化されるという事実にも言及しています。

編集後:コンテナビューを別のビューコントローラに埋め込む場合、その埋め込みビューのコントローラは、self.childViewControllers(配列になるため、1つしかない場合は、lastObjectで取得できます)を使用して、含まれているコントローラから参照できます。 。

于 2012-10-01T15:58:53.967 に答える
3

これに関する別のスレッドは次のとおりです。親iOSからContainerViewControllerにアクセスします

彼らは、prepareForSegueに参照を保持するか、 self.childViewControllersに埋め込まれたviewControllerを検索することを提案しています。

于 2014-11-04T11:17:50.203 に答える
0

注意事項

この質問への回答を使用する前に、埋め込まれているものが本当にビューコントローラである必要があるかどうかを検討することをお勧めします。

たとえば、UICollectionViewControllerサブクラスを埋め込む場合、代わりにUICollectionViewサブクラスを埋め込むことができますか?または、さらに良いことに、単純なViewModelUIViewの背後に隠れているサブクラスを埋め込むことができますか?UICollectionView

現在取り組んでいるコードベースでは、2つのViewControllerを別のViewControllerに埋め込んでいます。どちらも、代わりにかなり簡単にプレーンビューにすることができ、この厄介なコードがなくても、ストーリーボードでより簡単にバインドできます。

残念ながら、それらは現在ビューコントローラであり、私は現在、それらを単純なビューに単純化する立場にないので、これを行う必要があります。

バックグラウンド

ここでPlayfulGeekprepare(for segue:, sender:)が提案したように、埋め込みセグエをピックアップするアプローチを使用しています。

かなり整頓されているように見えるので、これに使用している迅速さを示したかったのですが…</ p>

class EditionLandingViewController: UIViewController {
    fileprivate var titlesView: SectionTitlesViewController!
    fileprivate var sectionsView: SectionsViewController!
}

//MARK:-

extension EditionLandingViewController {
    private enum SegueId: String {
        case embedTitles
        case embedSections
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        guard
            let segueRawId = segue.identifier,
            let segueId = SegueId(rawValue: segueRawId)
            else { return }

        switch segueId {
        case .embedTitles:
            self.titlesView = segue.destination as! SectionTitlesViewController

        case .embedSections:
            self.sectionsView = segue.destination as! SectionsViewController
        }
    }
}

討論

アクションメソッドとしてセグエに名前を付けることにしました。

セグエ識別子にケースを使用するenumということは、コンパイラーとツールが自分の側にあることを意味するため、セグエ名を間違えるのははるかに困難です。

この場合、セグエIDをスコープprivate enum内に保持することは適切であると思われます。これは、これらのセグエが他の場所では必要ないためです(たとえば、編集extensionできません)。perform

埋め込まれたViewControllerに暗黙的にラップされていない型を使用しています。これは、(私の場合はとにかく)それらが欠落していると論理エラーになるためです。

同様に、宛先のViewControllerタイプを強制的にキャストすることもできます。繰り返しますが、これらのタイプが同じでない場合は論理エラーになります。

于 2018-04-25T07:59:03.507 に答える
0

投票数の多い回答の迅速なバージョン。数年後、Interface Builderは、IBOutletsの埋め込みコンテナビューへのドラッグをまだサポートしていないようです。

代わりに、アウトレットをprepare(for:sender:):に設定します。

@IBOutlet var someViewController: SomeViewController!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "EmbedSomeViewController", let destination = segue.destination as? SomeViewController {
        someViewController = destination
    }
}

また、ストーリーボードでUIContainerViewを設定する必要があります。Xcodeは埋め込みセグエを自動的に生成します。セグエを設定しIdentifierます。

ストーリーボードに識別子を設定する

于 2021-09-21T01:52:54.503 に答える