La "vue conteneur" d'un storyboard est juste un standard UIView
objet. Il n'existe pas de type spécial de "vue conteneur". En fait, si vous regardez la hiérarchie des vues, vous pouvez voir que la "vue conteneur" est un objet standard de type UIView
:
Pour y parvenir de manière programmatique, vous utilisez le "confinement du contrôleur de vue" :
- Instanciez le contrôleur de vue enfant en appelant
instantiateViewController(withIdentifier:)
sur l'objet storyboard.
- Appelez
addChildViewController
dans votre contrôleur de vue parent.
- Ajoutez le contrôleur de vue
view
à votre hiérarchie de vues avec addSubview
(et définir également le frame
ou des contraintes, selon le cas).
- Appelez le
didMove(toParentViewController:)
sur le contrôleur de vue enfant, en passant la référence au contrôleur de vue parent.
Voir Mise en œuvre d'un contrôleur de vue de conteneur dans le Guide de programmation du contrôleur de vue et la section "Implémentation d'un contrôleur de vue conteneur" du document _Référence de classe UIViewController ._
Par exemple, en Swift 3, cela pourrait ressembler à ceci :
override func viewDidLoad() {
super.viewDidLoad()
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChildViewController(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
controller.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
controller.view.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
controller.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10)
])
controller.didMove(toParentViewController: self)
}
Notez que l'opération ci-dessus n'ajoute pas réellement une "vue conteneur" à la hiérarchie. Si vous voulez le faire, vous devez faire quelque chose comme.. :
override func viewDidLoad() {
super.viewDidLoad()
// add container
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(containerView)
NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
containerView.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10),
])
// add child view controller view to container
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChildViewController(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
controller.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
controller.view.topAnchor.constraint(equalTo: containerView.topAnchor),
controller.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
])
controller.didMove(toParentViewController: self)
}
Ce dernier modèle est extrêmement utile si vous passez d'un contrôleur de vue enfant à un autre et que vous voulez simplement vous assurer que la vue d'un enfant se trouve au même endroit que la vue de l'enfant précédent (c'est-à-dire que toutes les contraintes uniques pour le placement sont dictées par la vue conteneur, plutôt que de devoir reconstruire ces contraintes à chaque fois). Mais si vous n'effectuez qu'un simple confinement de vue, la nécessité de cette vue conteneur séparée est moins impérieuse.
Pour les rendus de Swift 2, voir révision précédente de cette réponse .
1 votes
Que voulez-vous dire lorsque vous dites "lorsque les contraintes sont correctement définies, la vue (enfant) s'adaptera aux changements de taille de la vue conteneur" (ce qui implique que ce n'est pas vrai lorsque vous faites du confinement de contrôleur de vue) ? Les contraintes fonctionnent de la même manière, que vous utilisiez la vue du conteneur dans IB ou le confinement du contrôleur de vue de manière programmatique.
1 votes
La chose la plus importante est l'intégration
ViewController
Le cycle de vie de l'entreprise. L'embarquéViewController
Le cycle de vie d'une personne ajoutée par Interface Builder est normal, mais celui d'une personne ajoutée de manière programmatique a été modifié.viewDidAppear
ni l'un ni l'autreviewWillAppear(_:)
niviewWillDisappear
.2 votes
@DawnSong - Si vous effectuez correctement les appels au contenu de la vue, la fonction
viewWillAppear
yviewWillDisappear
sont appelés sur le contrôleur de vue enfant, tout va bien. Si vous avez un exemple où ils ne le sont pas, vous devriez clarifier, ou poster votre propre question demandant pourquoi ils ne le sont pas.