web-dev-qa-db-fra.com

UIViewController -viewDidLoad n'est pas appelé

Étant nouveau sur Cocoa, j'ai quelques problèmes avec Interface Builder, UIViewController et amis.

J'ai une sous-classe UIViewController avec un UIView défini dans un xib, et avec la sortie de vue du contrôleur connectée à la vue. Le "propriétaire du fichier" de xib est défini comme sous-classe myViewcontroller .

Dans cette seule instance, le code suivant pour charger le contrôleur/vue (à partir du contrôleur de vue principal) ne fonctionne pas comme prévu:

if ( self.myViewController == nil )
{
    self.myViewController = [[MyViewController alloc]
        initWithNibName:@"MyViewController" bundle:nil];
}

[self.navigationController 
    pushViewController:self.myViewController animated:YES];

Dans les méthodes de MyViewController, j'ai placé des points d'arrêt et des messages de journal pour voir ce qui se passe:

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        NSLog(@"initWithNibName\n");
    }

    return self;
}

-(void)viewDidLoad {

    [super viewDidLoad];
    NSLog(@"viewDidLoad\n");
}

Résultat attend

Tous les deux -initWithNibName et -viewDidLoad les méthodes sont appelées et la vue de myViewController s'affiche.

Résultat observé

Seulement -initWithNibName est appelé, la vue n'est pas affichée.

Ai-je raté quelque chose? Quelqu'un peut-il recommander quelque chose à vérifier? (En particulier dans l'outil merveilleusement opaque Interface Builder).

31
Justicle

Ok, j'ai une réponse partielle - peut-être que les gourous peuvent en expliquer davantage. Le problème est:

[self.navigationController pushViewController:myViewController animated:YES];

En y regardant de plus près, dans ce cas self.navigationController est nul - donc le message Push ne va nulle part.

Au lieu de cela, si j'envoie:

[self.view addSubview:self.myViewController.view];

Ensuite, la vue apparaît et -viewDidLoad est appelé.

Je ne sais pas vraiment pourquoi self.navigationController n'est pas défini dans cette instance - la seule chose à laquelle je peux penser est que self est une sous-classe de UIViewController plutôt que UITableViewController (où le pushViewController le code vient).

De plus, laisser silencieusement les messages aller à zéro semble être une mauvaise idée, bien que ces réponses disent le contraire. Voir aussi ma question ici .

Édition finale:

Dans les commentaires ci-dessous, j'ai réalisé que la fonction d'affichage que je recherchais réellement (étant donné que monViewController est modal) est:

[self presentModalViewController:myViewController animated:YES];

Merci à tous pour leurs réponses utiles.

14
Justicle

RE: SOLUTION TROUVÉE !!!!!

En effet, cela semble être une solution de travail, mais la vraie astuce n'est pas de définir le view.hidden propriété à NO, ce qui fait que la vue se charge depuis le fichier nib est l'appel de UIViewController's méthode de vue, la vue n'est réellement chargée à partir de la nib que lorsque la méthode de vue est appelée pour la première fois.

En ce sens, un simple [viewController view] le message forcerait la vue à se charger à partir du fichier nib.

33
Jader Feijo

SOLUTION TROUVÉE !!!!!

Même quelque chose d'aussi inoffensif que cela rend possible l'appel de méthode viewDidLoad.

Insérez ce droit après alloc initWithNibName

viewController.view.hidden = NO; //calls viewDidLoad

Il est possible que vous n'ayez pas lié le supposé ViewController dans main.storyboard Du Identity Inspector Au class personnalisé que vous avez créé. Vous pourrez peut-être naviguer vers ce contrôleur à partir d'autres contrôleurs de vue via des séquences, mais aucun des viewDidLoad(), viewWillAppear() etc. ne sera exécuté.

5
Yash Tamakuwala

Utilisez simplement

- (void)viewDidAppear:(BOOL)animated{ 
        [super viewDidAppear:animated];
        //Your Code here
  }

au lieu de la méthode viewDidLoad.

5
Lolloz89

assurez-vous que la sortie de la vue dans le propriétaire du fichier (votre sous-classe viewController) est connectée à la vue réelle (c'est-à-dire le canevas 480X320 que vous voyez sur votre écran que vous utilisez pour construire votre interface utilisateur)

4
zpesk

Une autre raison, assez évidente rétrospectivement: si viewController.view est défini dans le code, puis l'événement viewDidLoad ne se déclenchera pas.

3
nmr

Cela ressemble à un problème de capitalisation pour moi. Vous faites référence à la classe MyViewController au lieu de la propriété myViewController dans l'appel à pushViewController.

3
slf

Vérifiez votre journal d'exécution pour les erreurs. Il est presque certain que la NIB ne se charge pas et il devrait y avoir une erreur à cet effet. La cause la plus probable est le fait de ne pas le mettre dans le bundle. Regardez dans votre phase de build "Copy Resources" et assurez-vous que le XIB est réellement copié. Construisez pour le simulateur, descendez dans le répertoire de construction et assurez-vous que la NIB est dans le bundle .app.

2
Rob Napier