複数のビューコントローラーを使用して管理する複雑なiPadビューがあります。私は以前(iOS6/XCode 4.5より前)、コードでビューコントローラーを割り当てることでこれを行い、マスタービューへのリンクを介してさまざまなビューをフックしました。
私がやりたいことは、新しいコンテナビューを使用して、ストーリーボードファイルにビューコントローラを埋め込むことです。埋め込みコントローラーからマスターコントローラーへのIBOutletリンクを作成できないようです。
これは可能ですか?または、コード内のタグまたは何かを介して組み込みコントローラーを取得するには?
この質問は、特にコンテナビューの使用に関するものです
「組み込みコントローラーを取得する」という意味がわかりません。コントローラーを使用する場合は、UIStoryboardメソッドのinstantiateViewControllerWithIdentifier:を使用し、IBでコントローラーに指定した識別子を使用します。また、performSegueWithIdentifier:sender:メソッドを使用することもできます(これにより、ビューコントローラもインスタンス化されます)。 Apple docsの「アプリでのビューコントローラーの使用」セクションを確認してください。子ビューコントローラーがコンテナーコントローラーと同時にインスタンス化されるという事実にも言及しています。
編集後:コンテナービューを別のビューコントローラーに埋め込む場合、その埋め込みビューのコントローラーは、それを含むコントローラーからself.childViewControllersで参照できます(配列になるため、1つしかない場合は、lastObjectで取得できます)。 。
場合によっては、-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;
}
}
これに関する別のスレッドを次に示します。 親iOSからContainer View Controllerにアクセス
参照を prepareForSegue に保持するか、または埋め込まれたviewControllerを self.childViewControllers で検索することを提案します
この質問への回答の使用に進む前に、埋め込まれたものが本当にビューコントローラーである必要があるかどうかを反映したい場合があります。
たとえば、UICollectionViewController
サブクラスを埋め込む場合、代わりにUICollectionView
サブクラスを埋め込むことができますか?または、さらに良いことに、UIView
サブクラスを埋め込んで、UICollectionView
を単純なViewModelの背後に隠すことができますか?
現在取り組んでいるコードベースで、2つのビューコントローラーを別のビューコントローラーに埋め込みます。どちらもかなり簡単に単純なビューになり、この面倒なコードがなければ、ストーリーボードでより簡単にバインドできます。
残念ながら、それらは現在ビューコントローラーであり、私は現在それらをプレーンビューに単純化する立場にないので、これを行う必要があります。
Playful Geek で提案されているように、prepare(for segue:, sender:)
の埋め込みセグエを取得する方法を使用しています。
Swiftこれはかなり整頓されているように見えるので、私はこれに使用しています...
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
edにすることはできません)。
埋め込みビューコントローラーに暗黙的にラップされていない型を使用しています。なぜなら、(いずれにしても)欠落している場合は論理エラーだからです。
同様に、宛先のビューコントローラタイプを強制的にキャストしてもかまいません。繰り返しますが、これらのタイプが同じでない場合は、論理エラーになります。