considérez le scénario suivant: J'ai une application basée sur un storyboard. J'ajoute un objet ViewController au storyboard, ajoute les fichiers de classe pour ce ViewController dans le projet et spécifie le nom de la nouvelle classe dans l'inspecteur d'identité IB. Maintenant, comment vais-je faire référence à ce ViewController par programmation à partir de AppDelegate? J'ai créé une variable avec la classe appropriée et l'ai transformée en propriété IBOutlet, mais je ne vois aucun moyen de faire référence au nouveau ViewController dans le code - toute tentative de ctrl-glisser une connexion ne fonctionne pas .
c'est-à-dire que dans l'AppDelegate, je peux accéder au ViewController de base comme ceci
(MyViewController*) self.window.rootViewController
mais qu'en est-il de tout autre ViewController contenu dans le storyboard?
la source
Réponses:
Jetez un œil à la documentation de
-[UIStoryboard instantiateViewControllerWithIdentifier:]
. Cela vous permet d'instancier un contrôleur de vue à partir de votre storyboard à l'aide de l'identifiant que vous avez défini dans l'inspecteur d'attributs IB:EDITED pour ajouter un exemple de code:
la source
[[[self window] rootViewController] storyboard]
selon la documentation, cela retournera le "storyboard à partir duquel le contrôleur de vue est issu." (ou nul s'il ne provient pas d'un storyboard). À partir de cet UIStoryboard *, vous pouvez utiliser les appels d'instanciation mentionnés par @RobinSummerhill. Notez que les storyboards instancient de nouvelles instances de vos viewControllers ( scènes ) au fur et à mesure qu'elles sont nécessaires et ne réutilise pas celles qui ont été précédemment visualisées.Si vous utilisez
XCode
5, vous devez le faire d'une manière différente.UIViewController
dansUIStoryboard
Identity Inspector
volet supérieur droitUse Storyboard ID
caseStoryboard ID
champEnsuite, écrivez votre code.
la source
En règle générale, le système doit gérer l'instanciation du contrôleur de vue avec un storyboard. Ce que vous voulez, c'est parcourir la hiérarchie viewController en saisissant une référence aux
self.window.rootViewController
contrôleurs de vue par opposition à l'initialisation, qui devrait déjà être initialisé correctement si vous avez correctement configuré votre storyboard.Donc, disons que vous
rootViewController
êtes un UINavigationController et que vous voulez envoyer quelque chose à son contrôleur de vue de dessus, vous le feriez comme ceci dans votre AppDelegatedidFinishLaunchingWithOptions
:Dans Swift, ce serait très similaire:
Vous ne devriez vraiment pas initialiser les contrôleurs de vue en utilisant les identifiants de storyboard du délégué de l'application, sauf si vous souhaitez contourner la façon normale de charger le storyboard et de charger vous-même l'ensemble du storyboard. Si vous devez initialiser des scènes depuis AppDelegate, vous faites probablement quelque chose de mal. Je veux dire, imaginez que vous, pour une raison quelconque, souhaitez envoyer des données à un contrôleur de vue en bas de la pile, l'AppDelegate ne devrait pas atteindre la pile de contrôleurs de vue pour définir les données. Ce n'est pas son affaire. C'est le business est le rootViewController. Laissez rootViewController gérer ses propres enfants! Donc, si je contournais le processus de chargement normal du storyboard par le système en supprimant les références à celui-ci dans le fichier info.plist, je voudrais au plus instancier le rootViewController en utilisant
instantiateViewControllerWithIdentifier:
, et éventuellement sa racine s'il s'agit d'un conteneur, comme un UINavigationController. Ce que vous voulez éviter, c'est d'instancier des contrôleurs de vue qui ont déjà été instanciés par le storyboard. C'est un problème que je vois souvent. En bref, je ne suis pas d'accord avec la réponse acceptée. C'est incorrect à moins que les affiches ne signifient de supprimer le chargement du storyboard de info.plist puisque vous aurez chargé 2 storyboards autrement, ce qui n'a aucun sens. Ce n'est probablement pas une fuite de mémoire car le système a initialisé la scène racine et l'a assignée à la fenêtre, mais ensuite vous êtes venu et vous l'avez instanciée à nouveau et l'avez affectée à nouveau. Votre application a bien mal démarré!la source
la source