2010-08-26 7 views
2

J'essaie de charger ma hiérarchie de vue via des appels à loadNibNamed.Comment charger plusieurs fichiers nib avec NSBundle loadNibNamed :?

Pour une seule pointe, dans mon ApplicationViewController : UIViewController:

- (void) loadView { 
    [super loadView]; 
    [[NSBundle mainBundle] loadNibNamed:@"ApplicationViewController" 
            owner:self options:nil]; 
} 

Mais dans SubViewController : ApplicationViewController:

- (void) loadView { 
    [super loadView]; 
    [[NSBundle mainBundle] loadNibNamed:@"SubViewController" 
            owner:self options:nil]; 
} 

Quand j'init SubViewController, la vue ne contient son propre fichier nib, comment puis-je obtenir ceux de super aussi?

J'ai essayé d'insérer les objets retournés de l'appel à NSBundle, de nouveau dans la hiérarchie de vue de l'appelant UIViewController, mais cela n'a pas fonctionné et certains problèmes de moulage m'empêchent de pouvoir déboguer ceci ...

Répondre

5

Ce qui se passe probablement dans votre exemple est que dans les deux fichiers nib vous définissez la sortie view. Ce qui se passe est alors le deuxième fichier nib chargé écrasent la valeur de la view propriété définie par le premier fichier nib:

@implementation SubViewController 

- (void) loadView 
{ 
    [super loadView]; 
    // at this point, self.view points to the view loaded from 
    // ApplicationViewController.nib 
    [[NSBundle mainBundle] loadNibNamed:@"SubViewController" 
           owner:self options:nil]; 
    // but at this point, self.view is overwritten with the view from 
    // SubViewController.nib 
} 
... 
@end 

Donc ce que vous pouvez faire est ceci: dans votre classe SubViewController, déclare une autre prise, par exemple comme ceci:

@property (nonatomic, retain) IBOutlet UIView* viewForSubController; 
//you can probably think of a better name for it. 

et dans votre fichier xib, ne pas l'ensemble de la propriété view, mais que l'ensemble viewForSubController. Et puis dans le loadView faire quelque chose comme:

@implementation SubViewController 

- (void) loadView 
{ 
    [super loadView]; 
    // at this point, self.view points to the view loaded from 
    // ApplicationViewController.nib 
    [[NSBundle mainBundle] loadNibNamed:@"SubViewController" 
           owner:self options:nil]; 
    // now, self.viewForSubController points to the view loaded from 
    // SubViewController.nib 

    // so now we can do this: 
    [self.view addSubview: self.viewForSubController]; 
} 
... 
@end 

Ou quelque chose dans ce sens.

+0

Exactement ce qui se passait, j'ai réussi à le faire fonctionner en ajoutant un IBOutlet pour chaque niveau de la hiérarchie de vue, peut-être se sentir un peu hacky, mais je suis heureux avec jusqu'à présent ... – julien

2

tout d'abord, je charge généralement Nibs avec quelque chose comme ce qui suit, puis attribuez-lui ce contrôleur à un membre retenu de son contrôleur mère ...

self.myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; 

Ainsi, chaque contrôleur de vue des charges contrôleurs des opinions exprimées . Ensuite, vous pouvez ou ne pas avoir à ajouter explicitement la vue des contrôleurs (myViewController.view) au parent avec un appel à:

[window addSubview: myController.view]; 

Vous pouvez consulter Apple QuartzDemo ou UICatalog pour un exemple de code qui charge Beaucoup d'enfants voient les contrôleurs, bien qu'ils l'ajoutent à une liste au lieu d'une vue.

+0

J'ai modifié ma question à mettre l'accent sur la situation de la sous-classe que je vais avoir, ce qui me empêcherait de le faire, ne serait-il? – julien

+0

Si la propriété myViewController est conservée, cela entraînera une fuite de mémoire. – Jonny

0

Vous ne devriez vraiment pas charger à partir d'une plume dans loadView. Le but de substituer cette méthode est de créer vos propres vues par programme. Vous pouvez appeler initWithNibName: à partir de l'init standard, mais il semble que vous essayez de composer deux vues ensemble. Je ne pense pas que le sous-classement va faire ce que vous voulez. Vous pouvez faire en sorte que la vue parent charge la vue enfant et ajouter sa propriété view à la hiérarchie de vue parent. Est-ce ce que vous essayez de faire?

Questions connexes