Une vue de conteneur peut être facilement ajoutée dans un storyboard via l'éditeur d'interface. Lorsqu'elle est ajoutée, une vue de conteneur est une vue d'espace réservé, une séquence incorporée et un contrôleur de vue (enfant).
Cependant, je ne parviens pas à trouver un moyen d'ajouter une vue de conteneur par programmation. En fait, je ne suis même pas capable de trouver une classe nommée UIContainerView
ou ainsi.
Un nom pour la classe de Container View est certainement un bon début. Un guide complet comprenant la suite sera très apprécié.
Je connais le Guide de programmation de View Controller, mais je ne le considère pas comme identique à la manière dont Interface Builder le fait pour Container Viewer. Par exemple, lorsque les contraintes sont correctement définies, la vue (enfant) s'adapte aux changements de taille dans Container View.
la source
ViewController
cycle de vie de l ' embarqué . LeViewController
cycle de vie de l ' embarqué par Interface Builder est normal, mais celui ajouté par programmationviewDidAppear
ne l' aviewWillAppear(_:)
ni ni niviewWillDisappear
.viewWillAppear
etviewWillDisappear
sont appelés sur le contrôleur de vue enfant, très 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.Réponses:
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 standardUIView
:Pour y parvenir par programme, vous utilisez le «confinement du contrôleur de vue»:
instantiateViewController(withIdentifier:)
l'objet storyboard.addChild
votre contrôleur de vue parent.view
à votre hiérarchie de vues avecaddSubview
(et définissez également lesframe
contraintes ou selon le cas).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 à:
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:
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
defalse
définir moi-même les contraintes. Vous pouvez évidemment laissertranslatesAutosizingMaskIntoConstraints
commetrue
et définir à la fois leframe
et leautosizingMask
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 .
la source
ViewController
cycle de vie de l ' embarqué . LeViewController
cycle de vie de l ' embarqué par Interface Builder est normal, mais celui ajouté par programmationviewDidAppear
ne l' aviewWillAppear(_:)
ni ni niviewWillDisappear
.ViewController
« sviewDidAppear
est appelé dans son parent deviewDidLoad
, au lieu de son cours de parentviewDidAppear
viewDidAppear
, [mais] niviewWillAppear(_:)
niviewWillDisappear
". Leswill
méthodes d'apparition sont appelées correctement dans les deux scénarios. Il faut appelerdidMove(toParentViewController:_)
quand on le fait par programme, mais sinon ils ne le feront pas. En ce qui concerne le moment de l'apparition. méthodes, elles sont appelées dans le même ordre dans les deux sens. Ce qui diffère, cependant, c'est le timing deviewDidLoad
, car avec l'intégration, il est chargé avantparent.viewDidLoad
, mais avec le programmatique, comme on pouvait s'y attendre, cela se produit pendantparent.viewLoadLoad
.translatesAutoresizingMaskIntoConstraints = false
. Je ne sais pas pourquoi c'est nécessaire ni pourquoi cela fait fonctionner les choses, mais merci de l'inclure dans votre réponse.@ Réponse de Rob dans Swift 3:
la source
Détails
Solution
Usage
Échantillon complet
Résultats
la source
tableViewController
unviewController
mais je ne peux pas définir le titre de l'ancien. Je ne sais pas s'il est possible de le faire. J'ai posté cette question . C'est gentil de ta part si tu y jettes un œil.Voici mon code dans swift 5.
}
Usage
Utilisez l'autre fonction d'intégration avec un contrôleur de vue sans storyboard.
la source
removeFromParent
appel empêche, comment modifieriez-vous votre classe pour permettre cela?