Impossible de définir le cadre correctement avant viewDidAppear

Je me demandais si quelqu'un sait pourquoi quand vous définissez le cadre d'une sous-vue dans viewDidLoad et viewWillAppear les modifications ne prennent pas d'effet sur l'écran, mais si vous le définissez dans viewDidAppear ils le font?

Dans mon cas, je charge un xib personnalisé avec deux vues de table puis je tente de les déplacer vers le bas dans viewDidLoad pour laisser de la place à une autre vue qui est ajoutée dans viewDidLoad car il n'est pas toujours nécessaire de l'afficher.

Le problème est quand je place l'image dans viewDidLoad ou viewWillAppear il est placé sur l'object, je peux voir en l'imprimant, mais il n'est pas reflété sur l'écran. Déplacer mes appels de trame set à viewDidAppear provoquera tout pour fonctionner comme prévu.

Est-ce mal de penser que je devrais pouvoir définir le cadre dans viewDidLoad ?

 - (id)init { if ( self = [super initWithNibName:@"MyView" bundle:nil] ) {} return self; } - (void)viewDidLoad { [super viewDidLoad]; self.descriptionWebView = [[[UIWebView alloc] initWithFrame:CGRectMake( 0, 0, self.view.frame.size.width, 200 )] autorelease]; [self.view addSubview:self.descriptionWebView]; self.tableView1.autoresizingMask = UIViewAutoresizingNone; self.tableView2.autoresizingMask = UIViewAutoresizingNone; [self.descriptionWebView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"...." withExtension:@"html"]]]; table1LocationWithHeader = CGRectMake( self.tableView1.frame.origin.x, 200, self.tableView1.frame.size.width, self.tableView1.frame.size.height - 200 ); table2LocationWithHeader = CGRectMake( self.tableView2.frame.origin.x, 200, self.tableView2.frame.size.width, self.tableView2.frame.size.height - 200 ); //this will NOT work self.tableView1.frame = table1LocationWithHeader; self.tableView2.frame = table2LocationWithHeader; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //this will NOT work self.tableView1.frame = table1LocationWithHeader; self.tableView2.frame = table2LocationWithHeader; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; //this WILL work self.tableView1.frame = table1LocationWithHeader; self.tableView2.frame = table2LocationWithHeader; } //I added these after comments for stack overflow users, it seems like viewDidLayoutSubviews is the best place to set the frame - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; //this will NOT work self.tableView1.frame = table1LocationWithHeader; self.tableView2.frame = table2LocationWithHeader; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; //this WILL work self.tableView1.frame = table1LocationWithHeader; self.tableView2.frame = table2LocationWithHeader; } 

viewDidLoad est appelée lorsque la class est chargée, mais aucun élément d'interface user n'a été initialisé. Par conséquent, toute tentative de reference sera écrasée ou indisponible pendant le process d'initialisation qui se produit entre les appels viewDidLoad et viewDidAppear. Une fois que tous les éléments de l'interface user ont été initiés et dessinés, viewDidAppear est appelée.

viewDidLoad – Appelée après le chargement de la vue du controller dans la memory

À ce stade, la vue n'est pas dans la hiérarchie de vue.

viewWillAppear – Indique au controller de vue que sa vue est sur le point d'être ajoutée à une hiérarchie de vue.

Encore une fois, la vue doit encore être ajoutée à la hiérarchie de vue.

viewDidAppear – Indique au controller de vue que sa vue a été ajoutée à une hiérarchie de vues.

Ce n'est qu'alors que la vue est ajoutée à la hiérarchie de vue.

Mettre à jour

viewDidLayoutSubviews est l'endroit le plus approprié pour modifier l'interface user avant qu'elle n'apparaisse à l'écran.

viewDidLayoutSubviews – Indique au controller de vue que sa vue vient de présenter ses sous-vues.

Voir ce fil Quand est-ce que layoutSubviews est appelé?
Lorsque vous utilisez autolayout, le framework n'appelle pas layoutSubviews automatiquement. C'est très important. De ref:

  • init ne provoque pas l'appel de layoutSubviews (duh)
  • addSubview: provoque l'appel de layoutSubviews sur la vue ajoutée, la vue à laquelle elle est ajoutée (vue cible) et toutes les sous-vues de la cible. …

Si vous ajoutez une sous-vue dans viewDidLoad, layoutSubviews est appelée avant viewDidAppear et vous pouvez get la taille correcte des sous-vues. Mais si vous ne faites rien, layoutSubviews sera appelé après viewDidAppear. C'est à votre code.

dans viewWillAppear ()

appelez layoutIfNeeded () une seule fois pour la vue dont vous voulez get l'image.

si tableView puis tableView.layoutIfNeeded () pour exmple