iOS AutoLayout: obtenga el ancho del tamaño del marco

Estoy desarrollando con el diseño automático de iOS 6

Me gustaría registrar un mensaje que muestre el ancho del marco de la vista.

Puedo ver textView en la pantalla.

Pero obtengo el ancho y la altura como cero, ¿me falta algo?

NSLog(@"textView = %p", self.textView); NSLog(@"height = %f", self.textView.frame.size.height); NSLog(@"width = %f", self.textView.frame.size.width); textView = 0x882de00 height = 0.000000 width = 0.000000 

Creo que el diseño automático no ha tenido tiempo de diseñar sus vistas para el momento en que las llama. El diseño automático no se ha producido cuando se llama a viewDidLoad , ya que se llama justo después de cargar las vistas y solo después de eso las vistas se colocan en la jerarquía de vistas del controlador de vistas y finalmente se distribuyen (en el método layoutSubviews la vista).

Editar: esta respuesta indica por qué el escenario de la pregunta no funciona. La respuesta de @ dreamzor señala dónde colocar su código para resolverlo.

En realidad, las respuestas anteriores no son del todo correctas. Los seguí y obtuve ceros una y otra vez.

El truco es colocar su código dependiente de viewDidLayoutSubviews método viewDidLayoutSubviews , que

Notifica al controlador de vista que su vista acaba de presentar sus subvistas.

No olvide que este método se llama varias veces y no forma parte del ciclo de vida de ViewController, así que tenga cuidado al usarlo.

Espero que sea útil para alguien.

Solo quería agregar, que para mi progtwig sin modo horizontal NO usar el diseño automático es mucho más simple … Lo intenté, aunque = D

Solución

  • Coloque ese código en viewDidAppear

Razón

  • viewDidLoad sucede antes de que termine el autolayout. Entonces, la posición todavía no está establecida por el diseño automático que se especificó en xib
  • viewDidAppear ocurre después de que se complete la ejecución automática.

Incluir en su viewDidLoad ()

 self.view.setNeedsLayout() self.view.layoutIfNeeded() 

Antes de acceder a yourview.frame.size.width

En realidad, logré forzar la actualización del diseño antes de mi código dentro de viewDidLoad :

 override func viewDidLoad() { super.viewDidLoad() println("bounds before \(self.previewContainer.bounds)"); //on iPhone 6 plus -> prints bounds before (0.0,0.0,320.0,320.0) self.view.setNeedsLayout() self.view.layoutIfNeeded() println("bounds after \(self.previewContainer.bounds)"); //on iPhone 6 plus -> prints bounds after (0.0,0.0,414.0,414.0) //Size dependent code works here self.create() } 

ACTUALIZACIÓN : Esto parece no funcionar más

Esta es una característica realmente extraña. Pero encontré:

Si quieres obtener un marco sin usar el método layoutsubviews, usa este:

 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"View frame: %@", NSStringFromCGRect(view.frame)); }); 

¡Esto es realmente extraño!

Ninguna de las respuestas anteriores funcionó por completo para mí, excepto viewDidLoad pero tiene el efecto secundario de no mostrar lo que quiero hasta que la vista se haya animado, lo que parece pobre.

viewDidLayoutSubviews debe ser el lugar correcto para ejecutar el código que depende de que se complete el autolayout, pero como otros han señalado, se lo llama varias veces en versiones recientes de iOS y no se puede saber cuál es la última llamada.

Así que resolví esto con un pequeño truco. En mi guión gráfico, mySubview debería ser más pequeño que el que contiene self.view . Pero cuando primero se llama a mySubview , mySubview todavía tiene un ancho de 600, mientras que self.view parece estar configurado correctamente (este es un proyecto de iPhone). Entonces, todo lo que tengo que hacer es monitorear las llamadas subsiguientes y verificar los anchos relativos. Una vez que mySubview es más pequeño que self.view , puedo estar seguro de que se ha distribuido correctamente.

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() if self.mySubview.bounds.size.width < self.view.bounds.size.width { // mySubview's width became less than the view's width, so it is // safe to assume it is now laid out correctly... } } 

Esto tiene la ventaja de no depender de números codificados, por lo que puede funcionar en todos los factores de forma de iPhone, por ejemplo. Por supuesto, puede no ser una panacea en todos los casos o en todos los dispositivos, pero probablemente haya muchas maneras ingeniosas de hacer comprobaciones similares de tamaños relativos.

Y no, no deberíamos tener que hacer esto, pero hasta que Apple nos dé algunas devoluciones de llamada más confiables, todos estamos atrapados con eso.

iOS AutoLayout: obtenga el ancho del tamaño del marco

  -(void) layoutSubviews{ [self layoutIfNeeded]; //right you code to set frame its will work to get frame and set frame. CALayer *bottomBorder = [CALayer layer]; bottomBorder.frame = CGRectMake(0.0f, bkView.frame.size.height - 1, bkView.frame.size.width, 1.0f); bottomBorder.backgroundColor = [UIColor blackColor].CGColor; [bkView.layer addSublayer:bottomBorder]; } 

Solo puede averiguar el tamaño después del primer pase de disposición. O simplemente llame al método siguiente luego de obtener el ancho real de su vista.

 [yourView layoutIfNeeded];