UIViewController crea con initWithNibName: paquete: oa través de un IBOutlet comportan de manera diferente

StackOverflow https://stackoverflow.com/questions/2257124

Pregunta

He encontrado un comportamiento extraño, y me gustaría ser explicado qué afirmación de que estoy haciendo lo que es malo.

En una clase AppDelegate de un proyecto WindowBased recién creado, añado un UIViewController a la ventana.
Puedo hacerlo de dos maneras diferentes:
 - con un IBOutlet. En IB, simplemente Instanced un UIViewController, set de su clase con el TestViewController y conectarlo (escenario A del Código).
 - la creación de la UIViewController con código (escenario B).

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    

#define USE_IBOUTLET YES // Comment this line to switch to scenario B

#ifdef USE_IBOUTLET
    // Scenario A

    [window addSubview:theTestViewController.view];
    [window makeKeyAndVisible];
#endif


#ifndef USE_IBOUTLET
    // Scenario B

    TestViewController *theTestViewControllerProgrammatically;

    theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil];

    // According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it
    [theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]];

    [window addSubview:theTestViewControllerProgrammatically.view];

    [window makeKeyAndVisible];
#endif
}

Como no hice ninguna personalización del objeto en IB, que debería tener el mismo comportamiento en ambos escenarios.

Escenario A, utilizando el IBOutlet funciona como se esperaba.
Pero el escenario B tiene los siguientes problemas:
 - La vista no está en la posición derecha (20 píxeles a alto, y cubierto por la barra de estado)
.  - La vista no cambia de tamaño correctamente (por ejemplo, tratar de cambiar la barra de estado de llamada)

¿Por qué?

archivo Zip del proyecto aquí si desea reproducir el problema: http : //dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zip

¿Fue útil?

Solución

Esto va a sonar muy tonto después de que mis respuestas de largo aliento, pero el problema que tienes es sencillo de solucionar (mediante programación).

Esta línea:

[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];

En realidad debería ser:

[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];

Se estaban colocando el marco para el VC establecido por IB, no por el que ha creado mediante programación.

De todos modos - vale la pena señalar que todos mis comentarios todavía se aplican! Todavía hay algunas cosas que usted tendrá que hacer mediante programación si no utiliza objetos del controlador del IB (por ejemplo, la creación de los elementos de la barra de navegación)

Paul

Otros consejos

He estado teniendo un problema muy similar a usted en que me di objetos VC no son todos iguales! El problema que estoy teniendo es establecer los elementos de la barra de navegación, simplemente parece que no puede hacerlo cuando el dueño del archivo es un controlador de vista objetivo que crear una instancia mediante programación. Sólo funciona si UnArchive objetos del controlador de IB.

He descargado su proyecto y tenía un juego un rato con él, y eso me hizo pensar un poco más acerca de lo que podría estar pasando. Creo que puedo dar una respuesta razonable, pero no estoy seguro si hay una solución simple ...

Lo que creo que está pasando es que Apple ha creado estas controlador de objetos en IB que son un poco más especializado. Una sugerencia esto podría ser cierto es que los objetos IB VC tienen un atributo se puede establecer que no tiene propiedad correspondiente directa para una clase UIViewController que puedo ver, por lo que objetos del controlador de IB pueden tener alguna funcionalidad adicional que subclases no IB UIViewController no puede tomar ventaja de. Dado que los objetos de una .xib son objetos completos '' liofilizados, Apple podría haber incluido todos los tipos de atributos particulares que no podemos ver o utilizar en sus versiones IB de ellos - esto puede tener algún efecto sobre cómo se inicializan los objetos .

Por ejemplo, en su MainWindow.xib, seleccione el objeto IB VC y se puede establecer atributos en él desde el inspector de paleta, como "Cambiar el tamaño de Vista a partir de cacao". Si elimina la marca de esto y vuelve a ejecutar la aplicación, verá el VC aparece exactamente como se ve en el escenario B. Como no puede ver este elemento cuando a partir de los atributos del archivo propietario (a pesar de que es como un UIViewController ), no es capaz de tomar ventaja de lo que se está haciendo por el controlador de vista para darle el comportamiento que desea.

El resultado de esto es que cuando se utiliza TestViewController.xib para inicializar el objeto de VC en el código, ninguno de los atributos específicos del IB de un VC se establecen, por lo tanto, se crea un UIViewController pantano-estándar, y así las cosas como el "cambio de tamaño Ver de SEMILLA" atributo y el establecimiento de la navegación de los artículos tienen que ser aplicadas a sí mismo.

Yo aún no he encontrado una manera de tomar ventaja de la funcionalidad que los controladores de vista del IB tienen cuando instanciarlas usando initWithNibName:bundle:nibBundle (supongo que es todo cosas privadas no podemos tener acceso), pero espero que esto podría haber dado que un punto de partida ...

Por supuesto, podría estar completamente equivocado y alguien me hará quedar como un completo idiota!

Paul

Es probable que en el caso B ese punto de vista no es consciente de la presencia de una barra de estado. Es necesario para cambiar su tamaño en consecuencia y ajustar su posición para tomar la barra de estado en cuenta. Esto se hace cambiando las propiedades marco (tamaño) y los límites (ubicación) de un UIView.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top