Une "vue conteneur" de storyboard n'est qu'un UIView
objet standard . Il n'y a pas de type spécial "vue conteneur". En fait, si vous regardez la hiérarchie des vues, vous pouvez voir que la "vue conteneur" est un standard UIView
:
Pour y parvenir par programme, vous utilisez le «confinement du contrôleur de vue»:
- Instanciez le contrôleur de vue enfant en appelant
instantiateViewController(withIdentifier:)
l'objet storyboard.
- Appelez
addChild
votre contrôleur de vue parent.
- Ajoutez le contrôleur de vue
view
à votre hiérarchie de vues avec addSubview
(et définissez également les frame
contraintes ou selon le cas).
- Appelez la
didMove(toParent:)
méthode sur le contrôleur de vue enfant, en transmettant la référence au contrôleur de vue parent.
Consultez Implémentation d'un contrôleur de vue de conteneur dans le Guide de programmation de contrôleur de vue et la section «Implémentation d'un contrôleur de vue de conteneur» de la référence de classe UIViewController .
Par exemple, dans Swift 4.2, cela pourrait ressembler à:
override func viewDidLoad() {
super.viewDidLoad()
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChild(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(toParent: self)
}
Notez que ce qui précède n'ajoute pas réellement une "vue conteneur" à la hiérarchie. Si vous voulez faire cela, vous feriez 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")
addChild(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(toParent: self)
}
Ce dernier modèle est extrêmement utile en cas de transition entre différents contrôleurs de vue enfant et vous voulez simplement vous assurer que la vue d'un enfant est au même endroit et 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 du conteneur, plutôt que de devoir reconstruire ces contraintes à chaque fois). Mais si vous effectuez simplement un confinement de vue simple, le besoin de cette vue de conteneur séparée est moins convaincant.
Dans les exemples ci-dessus, je me propose translatesAutosizingMaskIntoConstraints
de false
définir moi-même les contraintes. Vous pouvez évidemment laisser translatesAutosizingMaskIntoConstraints
comme true
et définir à la fois le frame
et le autosizingMask
pour les vues que vous ajoutez, si vous préférez.
Voir les révisions précédentes de cette réponse pour les rendus Swift 3 et Swift 2 .