Frage

Ich habe eine komplexe iPad-Ansicht, die ich mit mehreren Ansichtscontrollern verwalte.Ich habe dies zuvor (vor iOS6/XCode 4.5) getan, indem ich meine Ansichtscontroller im Code zugewiesen und die verschiedenen Ansichten über Links zur Masteransicht mit ihnen verbunden habe.

Ich möchte die neuen Containeransichten verwenden, um die Ansichtscontroller in die Storyboard-Datei einzubetten.Es scheint mir nicht möglich zu sein, eine IBOutlet-Verknüpfung vom eingebetteten View-Controller zum Master-Controller herzustellen.

Ist das möglich?Oder den eingebetteten Controller über ein Tag oder etwas im Code abrufen?

Bei dieser Frage geht es SPEZIELL um die Verwendung von Containeransichten

War es hilfreich?

Lösung

Ich bin nicht sicher, was Sie mit "den eingebetteten Controller abrufen".Wenn Sie einen Controller verwenden möchten, verwenden Sie die Uistoryboard-Methode InstantiateViewControllerWithIdentifier:, mithilfe der Bezeichner, die Sie dem Controller in IB angeben.Sie können den PerformingGewithIdentifier auch verwenden: Sender: Methode (die auch den Ansichtssteuergerät instanziiert).Sie sollten den Abschnitt "Verwenden von View-Controller in Ihrem App" in den Apple-Dokumenten ansehen.Es nimmt auch auf die Tatsache zu, dass Kinderansicht-Controller gleichzeitig mit dem Containercontroller instanziiert werden.

Nach dem Bearbeiten: Wenn Sie eine Containeransicht in einen anderen View-Controller einbetten, kann der Controller der Embedded Views von der mit Self.ChildViewController enthaltenden Controller referenziert werden (was ein Array ist, also, wenn nur eins vorhanden ist, können Sie es erhaltenmit Lastobject).

Andere Tipps

In einigen Fällen besteht eine weitere Möglichkeit darin, den eingebetteten Controller zu erfassen -prepareForSegue:sender:.

Wenn ich zum Beispiel eine habe UINavigationController eingebettet in a CustomContainerViewController, ich kann den Einbettungsabschnitt benennen embedContentStack im Storyboard und erfassen Sie es CustomContainerViewController über

- (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;
    }
}

Hier ist ein weiterer Thread darüber: Zugang Controller-Controller von Eltern iOS

Sie schlagen vor, einen Referenz in PrepardeforseSeGue "zu halten oder nach dem eingebetteten ViewController in self.childviewController

Hinweis zur Vorsicht

Bevor Sie mit der Beantwortung dieser Frage fortfahren, möchten Sie möglicherweise darüber nachdenken, ob die eingebetteten Dinge wirklich Ansichtscontroller sein müssen.

Wenn Sie beispielsweise eine einbetten UICollectionViewController Unterklasse, könnten Sie stattdessen eine einbetten? UICollectionView Unterklasse?Oder, noch besser, könnten Sie eine einbetten UIView Unterklasse, die das verbirgt UICollectionView hinter einem einfachen ViewModel?

In der Codebasis, an der ich gerade arbeite, bette ich zwei View-Controller in einen anderen View-Controller ein.Beide könnten stattdessen ziemlich einfach einfache Ansichten sein und könnten dann ohne diesen chaotischen Code einfacher in das Storyboard eingebunden werden.

Leider handelt es sich derzeit um Ansichtscontroller, und ich bin derzeit nicht in der Lage, sie in einfache Ansichten zu vereinfachen, daher muss dies genügen.

Hintergrund

Ich verwende den Ansatz, den Einbettungsübergang aufzugreifen prepare(for segue:, sender:) wie vorgeschlagen von Verspielter Geek Hier.

Ich wollte den Swift zeigen, den ich dafür verwende, da er ziemlich aufgeräumt zu sein scheint ...

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
        }
    }
}

Diskussion

Ich habe mich dafür entschieden Namenssegmente als Aktionsmethoden.

Mit einem enum Fälle für Segue-Bezeichner bedeuten, dass Sie den Compiler und die Tools auf Ihrer Seite haben, sodass es viel schwieriger ist, einen Segue-Namen falsch zu verstehen.

Behalten Sie die Segue-IDs in einem bei private enum innerhalb der extension Der Umfang erscheint in diesem Fall angemessen, da diese Segmente nirgendwo anders benötigt werden (das können sie auch nicht sein). performed, zum Beispiel).

Ich verwende implizit entpackte Typen für die eingebetteten View-Controller, weil es (zumindest in meinem Fall) einen logischen Fehler darstellt, wenn sie fehlen.

Ebenso erzwinge ich gerne die Umwandlung der Ziel-View-Controller-Typen.Auch hier wäre es ein logischer Fehler, wenn diese Typen nicht gleich wären.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top