6

Je rencontre un problème lors de la définition de la sortie de vue par défaut d'View Nib View Controller dans Interface Builder. Voici ma configuration:UINavigationController NIB nécessite que le propriétaire du fichier ait une vue?

J'ai une application TabBar où je charge un contrôleur de navigation en vue modal ...

MyNavCtrlrSubClass *menu = [[MyNavCtrlrSubClass alloc]initWithNibName:@"MenuController" bundle:nil]; 
[tabBarController presentModalViewController:menu animated:anim]; 

MenuController lui-même est structuré comme suit:

 
MenuController.xib 
    File's Owner (MyNavCtrlrSubClass : UIViewController) 
    Navigation Controller (UINavigationController) 
    Navigation Bar (UINavigationBar) 
    Root View Controller (Nib Name is set to load AnotherViewController.nib) 
     Navigation Item -> (UINavigationItem) 

Tout cela fonctionne correctement, sauf que lorsque MyNavCtrlrSubClass est chargé, j'obtiens l'erreur suivante:

Loaded the "MenuController" nib but the view outlet was not set

La raison pour laquelle cela se produit est claire: le propriétaire du fichier ne dispose pas d'une connexion de sortie pour sa vue. La question est ce que je devrais définir comme son point de vue, et quelque chose doit être mis en place en premier lieu? La barre de navigation est le seul candidat dans MenuController.xib, mais en faisant cela, il suffit de dimensionner UINavigationBar lui-même en mode plein écran, pour ainsi dire.

Je suis évidemment manquer quelque chose dans IB, mais quoi? MyNavCtrlrSubClass.m n'a pas de code lui-même, sauf un IBOutlet pour UINavigationController. Est-ce que je fais une erreur en essayant de tout mettre en place dans IB? L'idée est de garder le contrôleur de navigation modal en une seule plume, et toutes les vues qu'il charge dans des plumes séparées, mais comme MenuController est juste un conteneur pour la navigation et ne contient pas de vues, je le conçois mal. :)

Si vous vous demandez pourquoi je ne le conçois pas d'une autre manière, c'est parce que j'essaie d'obéir à ma perception (peut-être erronée) de la façon dont IB vous demande de construire une hiérarchie idéale.

Toute aide serait grandement appréciée.

Répondre

5

Je pense que vous ne comprenez peut-être pas comment le propriétaire du fichier doit être utilisé dans un fichier NIB. J'ai rédigé une réponse décrivant le propriétaire du fichier under another question.

Lorsque vous appelez cette ligne:

[[MyNavCtrlrSubClass alloc] initWithNibName:@"MenuController" bundle:nil] 

Vous créez une instance de MyNavCtrlrSubClass, et lui dire de charger @ "MenuController". Ensuite, dans le fichier MenuController.xib, il y a un second UINavigationController non lié avec des choses à l'intérieur. Lorsque MenuController.nib est chargé au moment de l'exécution, ce second contrôleur de navigation sera créé.

Un deuxième problème est qu'indiquer à un UINavigationController de charger un fichier NIB n'est pas vraiment judicieux car les contrôleurs de navigation créent et gèrent leurs propres vues. Vous voulez vraiment créer le contrôleur de vue racine et dire à ce contrôleur de vue de charger un fichier NIB.

Essayez ceci:

MyRootViewController *rootController = [[[MyRootViewController alloc] initWithNibName:@"AnotherViewController" bundle:nil] autorelease]; 
MyNavCtrlrSubClass *menu = [[MyNavCtrlrSubClass alloc] initWithRootViewController:rootController]; 

Si votre fichier XIB ressemble à ceci:

  • Propriétaire du fichier (réglé sur la sortie MyRootViewController, vue classe connectée à UIView ultérieure)
  • UIView
    • Sous-vue A
    • sous-vue B

Une fois que vous êtes à l'aise avec la façon dont tout cela fonctionne, vous pourriez aussi envisager instancier le contrôleur du contrôleur de navigation et vue racine dans un fichier XIB comme vous commencez à le faire dans le code vous avez posté.

+0

Merci pour votre réponse informative! Je suis sur le point de voir ce que je peux faire avec cela, et je reviendrai bientôt. Pour l'instant, laissez-moi vous demander: comment chargeriez-vous une nib de contrôleur de navigation modale, en concevant autant que possible dans Interface Builder? Est-il nécessaire, comme dans votre exemple, de configurer une puce View Controller, puis de créer le contrôleur de navigation par programmation, ou puis-je définir la hiérarchie de vue dans IB uniquement? –

+0

NOTE: il semble que la création programmatique du contrôleur de navigation signifierait que je dois également programmer sa propre hiérarchie de contrôleurs de vue par programmation, puis je m'éloigne de plus en plus de IB, en commençant par le contrôleur de navigation. –

+1

Vous pouvez créer un contrôleur de navigation et un contrôleur de vue racine dans le code et charger la vue du contrôleur de vue racine dans IB. Ce ne sera pas gênant. Vous pouvez également créer le contrôleur de navigation et son contrôleur de vue racine dans un XIB distinct de l'affichage du contrôleur de vue racine. Cette XIB distincte est généralement le MainWindow.xib. Lorsque le fichier MainWindow.xib est chargé, les deux contrôleurs de vue seront créés. Lorsque le contrôleur de vue racine a d'abord besoin de sa vue, il le chargera à partir du second fichier XIB. C'est la façon typique de le faire. –

0

Dans IB, dans la carte MenuController, ajoutez un UIView et définissez cette vue comme sortie. Vous devrez définir cette vue pour un UIViewController. Here est un lien rapide vers une page Apple montrant une configuration de base. Je ne sais pas si cela vous aidera à votre stade actuel.

+0

Le problème est qu'il n'y a aucune vue dans ma nib de contrôleur de navigation pour se connecter. Les contraintes sont que je veux séparer chaque plume individuelle, donc mon problème est conceptuel ou orienté design, pas un problème de mise en œuvre. Merci en tout cas. –

+0

Quelle vue est définie pour AnotherViewController? On dirait que c'est là que le problème est. – Jordan

+0

AnotherViewController est simplement une puce View Controller avec une seule vue. Ce n'est même pas chargé, cependant. Le problème se produit quelque part dans le cycle de vie quand MenuController veut une vue, mais au lieu de ce que j'espérais propager automagiquement la demande dans les contrôles, il jette juste l'erreur susmentionnée. Par votre réponse, cependant, il semble que vous impliquez un propriétaire de fichier nib n'a pas nécessairement besoin d'une plume. Est-ce votre compréhension? –

1

Le point crucial de cette question est dit par Travis lui-même: « Comment voulez-vous charger Navigation Controller nib, la conception autant que possible dans Interface Builder » Et à partir de l'exemple, il semble que cela signifie UINavigationController et UIViewControllers associés.

Avec cette interprétation, la réponse est que vous ne pouvez pas configurer complètement un UINavigationController et pour UIViewControllers en une seule XIB au catalogue. Oui, il est intuitif de vouloir le faire pour ne pas être fou.

Quand je dis que vous ne pouvez pas faire cela, je veux dire des méthodes les cadres les plus couramment utilisés ne sont pas une façon de gérer cela. Il n'y a pas de [UINavigationController alloc] initWithMegaNibName. Oui, vous pouvez remplir presque n'importe quoi dans un seul XIB et écrire du code pour hydrater des objets de manière spéciale, mais je ne pense pas que ce soit ce que vous cherchez. Vous pouvez utiliser deux ou plusieurs XIB comme Jon l'a suggéré, mais les choses sont moins autonomes et vous avez donc beaucoup de gens qui trouvent plus simple de faire partie ou la totalité des contrôleurs en code.

Malheureusement il n'y a pas 1: 1 entre la capacité d'interface correspondance Builder et code comme il est sur d'autres plateformes de dev. Je préfère généralement être en mesure de laisser les concepteurs participer autant que possible à la création d'actifs, mais la plupart d'entre eux que je connais ne codent pas l'objectif-c.

Questions connexes