Cómo get los frameworks de subViews en Storyboard

Solo quiero (por ahora) get las dimensiones de una subvista en la instanciación del controller de vista.

[Esta es una networkingucción a un caso tan simple que puedo encontrar de una pregunta anterior . Estoy intentando descubrir por qué subViews de escenas en Storyboards no se comportan de la forma esperada, es decir: como lo hacen los XIB, solo quiero get las dimensiones de mis subviews antes de que cualquier cosa esté dibujada en la pantalla]

Para condensar el problema a un proyecto nuevo y limpio, hago esto:

  • Cree un nuevo proyecto de vista única con "usar Storyboard" marcada
  • agregue una UIView única a la MainStoryboard_iPad.storyboard existente de MainStoryboard_iPad.storyboard (y cambie su background a verde para que sea más fácil de ver, más allá de networkingucir algunas dimensiones, este es el único cambio que hago desde la UIView pnetworkingeterminada que arrastre a la escena)
  • click el file ViewController.h en el browser para que aparezca en su propio marco debajo del cuadro Storyboard e inserte un par de llaves debajo de la directiva @interface
  • controle y haga clic y arrastre desde la vista UIV en el Storyboard hasta ViewController.h y dígale que nombre la salida firstViewFirstSubView

Entonces, ahora tenemos para ViewController.h :

 #import <UIKit/UIKit.h> @interface ViewController : UIViewController { IBOutlet UIView *firstViewFirstSubView; } @end 

Entonces, agrego este método al ViewController.m:

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSLog(@"View Controller will appear. firstViewFirstSubView: %@ ", firstViewFirstSubView); NSLog(@"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width, firstViewFirstSubView.frame.size.height, firstViewFirstSubView.frame.origin.x, firstViewFirstSubView.frame.origin.y); } 

En este punto, espero poder get las dimensiones de la subvista UIView. Sin embargo, obtengo todos los 0:

 2012-11-15 15:21:00.743 StoryboardViewBounds[11132:c07] View Controller will appear. firstViewFirstSubView: <UIView: 0x9379730; frame = (0 0; 0 0); autoresize = TM+BM; layer = <CALayer: 0x9378e40>> 2012-11-15 15:21:00.744 StoryboardViewBounds[11132:c07] subView's dimmensions: 0.000000 by 0.000000 at 0.000000, 0.000000 

¿Qué estoy haciendo mal? Parece que esto debería ser muy sencillo, así que creo que debo estar perdiendo algo simple, ya sea lanzando el interruptor correcto en el editor de Storyboard o implementando un método que Storyboard necesita.

Esas dimensiones se calculan y configuran cuando se realiza la llamada a layoutSubviews , que ocurre después de viewWillAppear . Después de que se layoutSubviews en UIVIew, puede get las dimensiones.

Observe viewDidLayoutSubviews implementar este método en su controller de vista: viewDidLayoutSubviews . En este punto, debería ser capaz de get las dimensiones de sus subvistas. Tenga en count que esta llamada está disponible a partir de iOS 5.0, pero dado que hace reference a guiones charts, supongo que está trabajando en o por encima de todos modos.

 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; NSLog(@"View Controller did layout subviews. firstViewFirstSubView: %@ ", firstViewFirstSubView); NSLog(@"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width, firstViewFirstSubView.frame.size.height, firstViewFirstSubView.frame.origin.x, firstViewFirstSubView.frame.origin.y); } 

Hay un problema relacionado que estoy obligado a abordar, que con suerte salvará a alguien más un día de debugging:

Estoy descubriendo eso en Storyboard:

  1. segue-push no hace que subView se -viewDidLayoutSubviews en -viewDidLayoutSubviews (en su lugar se presentan en otro momento justo antes -viewDidAppear ).
    Mientras
  2. segue-modal y [navController.storyboard presentViewController:] hace que se subViews -viewDidLayoutSubviews en -viewDidLayoutSubviews .

La solución es poner [self.mySubView layoutSubviews] dentro del método -viewDidLayoutSubviews 's -viewDidLayoutSubviews para cargar manualmente el subView s dentro de mySubView .

Mi caso fue que tenía un button de degradado personalizado que no estaba inicializando correctamente su aspecto visual.
El button estaba contenido en un scrollView que contenía un CustomView que contenía el button de degradado personalizado.
Entonces, básicamente … un button dentro de una vista dentro de scrollView .

La aplicación comienza con un UINavigationController con algún otro ViewController1 cargado.
ViewController1 contiene un button que, cuando se presiona, inicia un storyboard segue-push a ViewController2 .
( esto se organizó en el guión gráfico al arrastrar el control desde el button en ViewController1 a ViewController2 ).

ViewController2 contiene scrollview / customView / customButton .
En ViewController2 's -viewDidLayoutSubviews , inicializo el customButton que es un button de gradiente personalizado que tiene sus propios files .h / .m .
GradientButton.m tiene un método initLayers que lo configura gráficamente y requiere que se inicialice la propiedad bounds / frame del button.
Sin embargo
en ViewController2 's -viewDidLayoutSubviews , self.customButton tenía un marco de 0,0,0,0.

Algunas notas:

  1. Sí, estoy llamando [super viewDidLayoutSubviews] al comienzo de -viewDidLayoutSubviews .
  2. La única vista que se ha presentado en -viewDidLayoutSubviews es self.view (vista inicial ViewController2 , como está conectada en el panel de conexiones de Storyboard. En mi caso, self.view es un scrollView ).

Resolver:

  1. en ViewController2 , creé una salida self.bottomView para la vista que contenía self.customButton .
  2. en ViewController2 's -viewDidLayoutSubviews , llamo [self.bottomView layoutSubviews]
    • Esto hará que los cuadros / límites de customButton se configuren correctamente.
  3. A continuación, [self.customButton initLayers] que ahora inicializa correctamente mi button de degradado personalizado.

Algunas notas sobre ViewController2 's -viewDidLayoutSubviews: llamando [self.view layoutSubviews] hace que el marco de bottomView se inicialice, pero NO customButton de customButton .
En términos de una jerarquía de vista, las -layoutSubviews aplican solo a los subView de self.view y no a cualquier subView de dichos subView .
Esto solo parece ser el caso de storyboard segue-push .

El storyboard segue-modal y el programmatic [navController presentViewController] parecen inicializar correctamente todos los niveles de la jerarquía de vistas (todos " subView de subView s") en el momento en que se llama a -viewDidLayoutSubviews .