No se puede establecer el marco correctamente antes de viewDidAppear

Me preguntaba si alguien sabe por qué cuando establece el marco de una subvista en viewDidLoad y viewWillAppear los cambios no tienen efecto en la pantalla, pero si lo configura en viewDidAppear , ¿lo hacen?

En mi caso, estoy cargando un xib personalizado con dos vistas de tabla y luego intentando desplazarlas hacia abajo en viewDidLoad para permitir espacio para otra vista que se agrega en viewDidLoad ya que no siempre es necesario mostrarlo.

El problema es cuando marco el marco en viewDidLoad o viewWillAppear se establece en el object, puedo verlo imprimiéndolo, pero no se refleja en la pantalla. Al mover mis llamadas de fotogtwigs de set a viewDidAppear , todo funcionará como se espera.

¿Está mal pensar que debería poder establecer el marco en 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 se invoca cuando la class se carga, sin embargo, no se han inicializado los elementos ui y, por lo tanto, cualquier bash de referencerlos se sobreescribirá o no se podrá validar durante el process de initialization que ocurre entre las llamadas viewDidLoad y viewDidAppear. Una vez que se ha initalizado y dibujado todo el elemento ui, se llama a viewDidAppear.

viewDidLoad: se llama después de que la vista del controller se carga en la memory

En este punto, la vista no está dentro de la jerarquía de la vista.

viewWillAppear: notifica al controller de vista que su vista está a punto de ser agregada a una jerarquía de vistas.

Nuevamente, la vista aún no se ha agregado a la jerarquía de vistas.

viewDidAppear: notifica al controller de vista que su vista se agregó a una jerarquía de vistas.

Solo entonces se agrega la vista a la jerarquía de vistas.

Actualizar

El viewDidLayoutSubviews es el lugar más apropiado para modificar la interfaz de usuario antes de que aparezca realmente en la pantalla.

viewDidLayoutSubviews: notifica al controller de vista que su vista acaba de presentar sus subvistas.

Ver este hilo ¿ Cuándo se llama a layoutSubviews?
Cuando use autolayout, framework no llame a layoutSubviews automáticamente. Eso es muy importante De ref:

  • init no hace que se invoque layoutSubviews (duh)
  • addSubview: hace que se invoque el layoutSubviews en la vista que se agrega, la vista a la que se agrega (vista de destino) y todas las subvistas del objective. …

Si agrega subview en viewDidLoad, layoutSubviews llamado antes viewDidAppear, y puede get el tamaño correcto de subviews. Pero si no hace nada, se llamará a layoutSubview después de viewDidAppear. Depende de tu código.

en viewWillAppear ()

simplemente llame a layoutIfNeeded () una vez para la vista cuyo marco desea get.

si tableView luego tableView.layoutIfNeeded () para ejemplar