Eine Containeransicht kann einfach über den Schnittstelleneditor zu einem Storyboard hinzugefügt werden. Beim Hinzufügen besteht eine Containeransicht aus einer Platzhalteransicht, einem Einbettungsabschnitt und einem (untergeordneten) Ansichtscontroller.
Ich kann jedoch keine Möglichkeit finden, eine Containeransicht programmgesteuert hinzuzufügen. Eigentlich kann ich nicht einmal eine Klasse mit dem Namen UIContainerView
oder so finden.
Ein Name für die Klasse der Containeransicht ist sicherlich ein guter Anfang. Eine vollständige Anleitung einschließlich des Segues wird sehr geschätzt.
Mir ist das View Controller-Programmierhandbuch bekannt, aber ich betrachte es nicht als dasselbe wie Interface Builder für Container Viewer. Wenn beispielsweise die Einschränkungen ordnungsgemäß festgelegt sind, wird die (untergeordnete) Ansicht an die Größenänderungen in der Containeransicht angepasst.
quelle
ViewController
Lebenszyklus des Embedded . DerViewController
Lebenszyklus des Embedded durch Interface Builder ist normal, der programmgesteuert hinzugefügte jedochviewDidAppear
wederviewWillAppear(_:)
nochviewWillDisappear
.viewWillAppear
undviewWillDisappear
auf dem untergeordneten View Controller aufgerufen. Wenn Sie ein Beispiel haben, in dem dies nicht der Fall ist, sollten Sie dies klären oder Ihre eigene Frage stellen, warum dies nicht der Fall ist.Antworten:
Eine Storyboard- "Containeransicht" ist nur ein Standardobjekt
UIView
. Es gibt keinen speziellen Typ "Containeransicht". Wenn Sie sich die Ansichtshierarchie ansehen, sehen Sie, dass die "Containeransicht" ein Standard istUIView
:Um dies programmgesteuert zu erreichen, verwenden Sie "View Controller Containment":
instantiateViewController(withIdentifier:)
das Storyboard-Objekt aufrufen .addChild
Ihren übergeordneten View Controller auf.view
zu Ihrer Ansichtshierarchie hinzuaddSubview
(und legen Sie dieframe
oder Einschränkungen entsprechend fest).didMove(toParent:)
Methode auf dem untergeordneten Ansichtscontroller auf und übergeben Sie den Verweis an den übergeordneten Ansichtscontroller.Siehe Implementieren eines Container View Controllers im View Controller-Programmierhandbuch und im Abschnitt "Implementieren eines Container View Controllers" der UIViewController-Klassenreferenz .
In Swift 4.2 könnte es beispielsweise so aussehen:
Beachten Sie, dass oben keine "Containeransicht" zur Hierarchie hinzugefügt wird. Wenn Sie das tun möchten, würden Sie etwas tun wie:
Dieses letztere Muster ist äußerst nützlich, wenn Sie jemals zwischen verschiedenen untergeordneten Ansichtscontrollern wechseln und nur sicherstellen möchten, dass sich die Ansicht eines Kindes am selben Speicherort befindet und die Ansicht des vorherigen Kindes (dh alle eindeutigen Einschränkungen für die Platzierung werden von der Containeransicht vorgegeben). anstatt diese Einschränkungen jedes Mal neu erstellen zu müssen). Wenn Sie jedoch nur eine einfache Ansichtsbegrenzung durchführen, ist die Notwendigkeit dieser separaten Containeransicht weniger zwingend.
In den obigen Beispielen, Ich gründe
translatesAutosizingMaskIntoConstraints
auffalse
die Zwänge selbst zu definieren. Sie können offensichtlich verlassentranslatesAutosizingMaskIntoConstraints
wietrue
und hier sowohl dieframe
und dieautosizingMask
für die Ansichten , die Sie hinzufügen möchten , wenn Sie bevorzugen würden.Siehe frühere Überarbeitungen dieser Antwort für Swift 3- und Swift 2- Wiedergaben.
quelle
ViewController
Lebenszyklus des Embedded . DerViewController
Lebenszyklus des Embedded durch Interface Builder ist normal, der programmgesteuert hinzugefügte jedochviewDidAppear
wederviewWillAppear(_:)
nochviewWillDisappear
.ViewController
istviewDidAppear
in seinen Eltern genannt wirdviewDidLoad
, statt während seiner ElternviewDidAppear
viewDidAppear
, [aber] wederviewWillAppear(_:)
nochviewWillDisappear
". Diewill
angezeigten Methoden werden in beiden Szenarien korrekt aufgerufen. Man muss anrufen,didMove(toParentViewController:_)
wenn man es programmgesteuert macht, sonst werden sie nicht. In Bezug auf den Zeitpunkt des Auftretens. Methoden werden sie in beide Richtungen in derselben Reihenfolge aufgerufen. Was sich jedoch unterscheidet, ist das Timing vonviewDidLoad
, denn mit Embed wird es vorher geladenparent.viewDidLoad
, aber mit Programmatic, wie wir es erwarten würden, passiert es währendparent.viewLoadLoad
.translatesAutoresizingMaskIntoConstraints = false
. Ich weiß nicht, warum es gebraucht wird oder warum es funktioniert, aber ich danke Ihnen, dass Sie es in Ihre Antwort aufgenommen haben.@ Robs Antwort in Swift 3:
quelle
Einzelheiten
Lösung
Verwendung
Vollständige Probe
Ergebnisse
quelle
tableViewController
einen hinzuzufügenviewController
, kann aber den Titel des ersteren nicht festlegen. Ich weiß nicht, ob das möglich ist. Ich habe diese Frage gestellt . Es ist nett von dir, wenn du es dir ansiehst.Hier ist mein Code in Swift 5.
}}
Verwendung
Verwenden Sie die andere Einbettungsfunktion mit einem Nicht-Storyboard-Ansichts-Controller.
quelle
removeFromParent
Aufruf verhindert. Wie würden Sie Ihre Klasse ändern, um dies zuzulassen?