¿Por qué tengo que configurar manualmente el marco de mi vista en viewDidLoad?

Tengo una configuración bastante básica con un UINavigationController dentro de un UITabBarController. Quiero diseñar mediante progtwigción la vista de rootViewController de ese navcontroller, pero cuando miro self.view.frame dentro de viewDidLoad, obtengo esto (en el paisaje , por ejemplo):

1. view frame: {{20, 0}, {748, 1024}} // looks like an odd portrait mode 

Luego me autorroteo a Portrait y obtengo esto:

 2. view frame: {{0, 0}, {768, 911}} 

Luego, cuando regrese a Landscape, el marco ahora es este:

 3. view frame: {{0, 0}, {1024, 655}} 

Y otros eventos de autorrotación cambiarán entre los valores de fotogtwig # 2 y # 3.

Para superar la rareza de # 1, actualmente estoy haciendo esto en viewDidLoad:

 if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { self.view.frame = CGRectMake(0, 0, 768, 911); } else { self.view.frame = CGRectMake(0, 0, 1024, 655); } 

Siento que obviamente me falta algo aquí. ¿Por qué el marco predeterminado de la vista no coincidiría con el marco cuando se autorregresa a la misma orientación? ¿El marco de vista no se establece en la orientación inicial? Muy confundido…

Debo mencionar que ninguno de los anteriores, incluido mi truco kludgy, cambia nada visualmente. La razón por la que tengo el truco es que cuando diseño mis subvistas en esta vista, se basarán en el lugar donde espero que estén, que es la esquina superior izquierda debajo de la barra de navegación.

¿Qué estoy haciendo mal?

ACTUALIZACIÓN: desactivar todas las cosas de autosizing en la vista cambia resultado # 1 para ser:

 view frame: {{0, 0}, {748, 1024}} 

Eso parece un poco más cerca, pero aún no coincide con el # 3.

    No se garantiza que el marco sea el mismo en viewDidLoad como lo será cuando finalmente se muestre la vista. UIKit ajusta el marco de la vista del controlador de vista antes de mostrarlo, según el contexto en el que aparecerá. El tamaño se determina en función de la orientación de la interfaz y las dimensiones de cualquier barra de navegación visible, barra de tabs, barra de herramientas o barra de estado (que a su vez tiene un alto que puede cambiar, por ejemplo, cuando estás en una llamada telefónica).

    Ayuda a comprender qué sucede cuando se carga y muestra la vista de un controlador de vista:

    1. Algo accede a la propiedad de vista de su controlador de view por primera vez. Esto puede ocurrir en su propio código o en UIKit en respuesta a una acción del usuario como seleccionar una pestaña.

    2. UIKit carga de forma lenta la vista de su controlador de vista llamando a loadView si está definido, o cargando la vista desde el NIB que se especificó en initWithNibName:bundle: Si ninguno de los dos existe, UIKit simplemente carga una vista vacía.

    3. UIKit llama a viewDidLoad una vez que la vista y sus subvistas se han cargado por completo. En este punto, el marco de la vista será el configurado en el NIB o en loadView .

    4. Algo requiere que UIKit muestre la vista de su controlador de vista. Nuevamente, esto puede ser una acción del usuario como tocar en una pestaña, o una llamada a un método explícito en su código como pushViewController:animated: o presentModalViewController:animated:

    5. UIKit cambia el tamaño de la vista en función del contexto en el que se presentará, como se describe anteriormente.

    6. UIKit llama a viewWillAppear: El marco ahora debe ser el tamaño que se mostrará. (?) EDITAR: Esto ya no puede ser cierto. Ver los comentarios a continuación.

    7. UIKit muestra la vista, con o sin animaciones.

    8. UIKit llama a viewDidAppear:

    Como puede ver, si necesita saber el tamaño del marco de su vista antes de que se presente, viewWillAppear: es su única oportunidad. Recuerde que este tamaño puede cambiar después de que aparezca la vista por varias razones, incluidos los eventos de rotación o los cambios en la altura de la barra de estado. Por esta razón, es importante dar a cada subvista una apropiada mascando de autoresizing, para garantizar que el diseño se pueda ajustar adecuadamente para cualquier cambio en los límites.

    Si desea construir su jerarquía de vistas manualmente, el lugar recomendado para hacerlo es en loadView. Como usted mismo construye la vista en este método, puede inicializar su marco a lo que desee. El tamaño que elijas no importa mucho, ya que es probable que UIKit te lo cambie de todos modos. Solo asegúrate de configurar tus Autenticación Automática de manera apropiada.

    Habrá un método en tu clase

     - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return YES; } 

    Pon tu marco en este método … Entonces funcionará bien.

    Por ejemplo:

     - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations if(interfaceOrientation == UIDeviceOrientationPortrait || UIDeviceOrientationPortraitUpsideDown) self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinPOTRAIT, FRAME.HEIGHTinPOTRAIT); else if(interfaceOrientation == UIDeviceOrientationLandscapeRight || UIDeviceOrientationLandscapeLeft) self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinLANDSCAPE, FRAME.HEIGHTinLANDSCAPE); return YES; } 

    FRAME.WIDTH> width deseado FRAME.HEIGHT> altura deseada