objective-c ios uiview viewdidload viewdidappear

objective-c - view controller



No se puede establecer el marco correctamente antes de viewDidAppear (3)

Me preguntaba si alguien sabe por qué cuando configura el cuadro de una subvista en viewDidLoad y viewWillAppear los cambios no tendrán efecto en la pantalla, pero si lo establece en viewDidAppear , sí lo hacen.

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

El problema es que cuando configuro el marco en viewDidLoad o viewWillAppear se establece en el objeto, puedo verlo imprimiéndolo, pero no se refleja en la pantalla. Mover mis llamadas de marco establecido a viewDidAppear hará que todo funcione 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; }


Se llama a viewDidLoad cuando se carga la clase; sin embargo, no se han inicializado elementos de la interfaz de usuario y, por lo tanto, cualquier intento de referenciarlos se sobrescribirá o no será valioso durante el proceso de inicialización que ocurre entre las llamadas viewDidLoad y viewDidAppear. Una vez que todo el elemento ui ha sido inicializado y dibujado, se muestra viewDidAppear.

viewDidLoad: se llama después de que la vista del controlador se carga en la memoria

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

viewWillAppear: notifica al controlador de vista que su vista está a punto de agregarse a una jerarquía de vistas.

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

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

Sólo entonces se agrega la vista a la jerarquía de vistas.

Actualizar

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

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


Ver este hilo ¿ Cuándo se llama layoutSubviews?
Cuando se utiliza autolayout, el marco no llama a layoutSubviews automáticamente. Eso es muy importante. Desde ref:

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


Si agrega una subvista en viewDidLoad, layoutSubviews se llama antes de viewDidAppear, y puede obtener el tamaño correcto de subvistas. Pero si no hace nada, se invitará a layoutSubviews después de viewDidAppear. Depende de su código.


in viewWillAppear ()

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

si tableView entonces tableView.layoutIfNeeded () para ejemplo