Pregunta

Tengo una vista personalizada que no aparece. layoutSubview mensajes durante la animación.

Tengo una vista que llena la pantalla.Tiene una subvista personalizada en la parte inferior de la pantalla que cambia de tamaño correctamente en Interface Builder si cambio la altura de la barra de navegación. layoutSubviews Se llama cuando se crea la vista, pero nunca más.Mis subvistas están diseñadas correctamente.Si desactivo la barra de estado de la llamada entrante, la subvista layoutSubviews no se llama en absoluto, aunque la vista principal anima su cambio de tamaño.

¿En qué circunstancias es layoutSubviews realmente llamado?

Tengo autoresizesSubviews ajustado a NO para mi vista personalizada.Y en Interface Builder tengo configurados los puntales superior e inferior y la flecha vertical.


Otra parte del rompecabezas es que la ventana debe ser clave:

[window makeKeyAndVisible];

De lo contrario, las subvistas no cambian de tamaño automáticamente.

¿Fue útil?

Solución 5

Rastreé la solución a la insistencia de Interface Builder que los muelles no se pueden cambiar en una vista que tienen los elementos de la pantalla simuladas activadas (barra de estado, etc.). Desde los muelles estaban fuera de la vista principal, ese punto de vista no podía cambiar el tamaño y por lo tanto se ha desplazado hacia abajo en su totalidad cuando la barra de llamada entrante apareció.

En cuanto las características simuladas, luego cambiar el tamaño de la vista y el establecimiento de los resortes correctamente causó la animación a ocurrir y mi método a ser llamado.

Un problema adicional en la depuración de esto es que el simulador se cierra la aplicación cuando el estado de la llamada entrante se activa a través del menú. Dejar de aplicación = no depurador.

Otros consejos

Tenía una pregunta similar, pero no estaba satisfecho con la respuesta (ni con ninguna que pudiera encontrar en la red), así que lo intenté en la práctica y esto es lo que obtuve:

  • init no causa layoutSubviews para ser llamado (duh)
  • addSubview: causaslayoutSubviews para ser llamado a la vista que se está agregando, la vista que se está agregando añadido a (vista de destino), y todos los subvistas del destino
  • vista setFramellama inteligentemente layoutSubviews en La vista que solo tiene su marco establecido Si el parámetro de tamaño del fotograma es diferente
  • desplazamiento de UIScrollView Causas layoutSubviews para ser llamado scrollView, y su supervista
  • rotar un dispositivo solo llamalayoutSubview En la vista principal (la vista principal (la viewControllers primario que responde vista)
  • Cambiar el tamaño de una vista llamará layoutSubviews en su supervisión

Mis resultados - http://blog.logichigh.com/2011/03/16/when-does-layoutsubviews-get-call/

Sobre la base de la respuesta anterior por @BadPirate, experimenté un poco más y se acercó con algunas aclaraciones / correcciones. He descubierto que layoutSubviews: se llamará en una vista si y sólo si:

  • Sus propios límites (no enmarcar) cambiaron.
  • Los límites de uno de sus directos subvistas cambiaron.
  • Se añade una subvista a la vista o elimina de la vista.

Algunos detalles pertinentes:

  • Los límites son considerados sólo cambia si el nuevo valor es diferente, que incluye un origen diferente . Tenga en cuenta específicamente que es la razón por layoutSubviews: es llamada cuando un UIScrollView pergaminos, ya que realiza el desplazamiento cambiando el origen de sus límites.
  • cambiar el marco de sólo cambiará los límites si el tamaño ha cambiado, ya que esto es lo único que se propagó a la propiedad límites.
  • Un cambio en los límites de la opinión de que todavía no está en una jerarquía de vistas resultará en una llamada a layoutSubviews: cuando la vista se añadió finalmente a una jerarquía de vistas .
  • Y simplemente para la corrección: estos disparadores no lo hacen directamente llamar layoutSubviews, sino más bien llamar setNeedsLayout, que establece / levanta una bandera. Cada iteración del bucle de ejecución, para todos los puntos de vista en la jerarquía de vistas , se activa esta bandera. Para cada punto de vista donde se encuentra levantó la bandera, layoutSubviews: se llama en ella y la bandera se pone a cero. Vistas más arriba en la jerarquía serán comprobados / llamada en primer lugar.

https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5- SW1

  

Los cambios de configuración pueden ocurrir cuando cualquiera de los siguientes eventos ocurre   en una vista:

     

a. El tamaño de los cambios de límites del rectángulo de una vista.
  si. Un cambio de orientación de interfaz se produce, lo que normalmente provoca un cambio en la vista raíz límites del rectángulo.
  C. El conjunto de subcapas Core Animation asociados con cambios en la capa de la vista y requiere el diseño.
  re. Su diseño fuerzas de aplicación que se produzca llamando al método setNeedsLayout o layoutIfNeeded de una vista.
  mi. Su fuerzas de aplicación la disposición llamando al método setNeedsLayout del objeto de capa subyacente de la vista.

Algunos de los puntos en de BadPirate respuesta son sólo parcialmente cierto:

  1. Para el punto addSubView

      

    addSubview causa layoutSubviews para ser llamados en la vista que se añade, la vista está siendo añadido a (vista de destino), y todos los subvistas del objetivo.

    Depende (vista de destino) autoresize máscara de la vista. Si tiene autoresize máscara, layoutSubview será llamado en cada addSubview. Si no tiene máscara autoresize continuación layoutSubview se llamará sólo cuando (destino) Ver los cambios de tamaño de marco de la vista.

    Ejemplo: si ha creado UIView programación (no tiene máscara autoresize por defecto), LayoutSubview se llama sólo cuando el marco UIView no cambia en cada addSubview

    .

    Es a través de esta técnica que el rendimiento de la aplicación también se incrementa.

  2. En el punto de rotación dispositivo

      

    Rotación de un dispositivo de sólo llama layoutSubview en la vista padre (la respuesta de vista principal de viewController)

    Esto puede ser cierto sólo cuando el VC es en la jerarquía de VC (raíz en window.rootViewController), así que esto es el caso más común. En iOS 5, si crea un VC, pero no se ha agregado a cualquier otra VC, VC entonces este no obtendría ninguna notó cuando rote dispositivo. Por lo tanto, su opinión no sería llamar la atención llamando layoutSubviews.

llamadas [self.view setNeedsLayout]; en viewController hace que sea para llamar viewDidLayoutSubviews

¿Has mirado en layoutIfNeeded?

El fragmento de la documentación se encuentra por debajo. ¿El trabajo de animación si se llama a este método de forma explícita durante la animación?

layoutIfNeeded Expone la subvistas si es necesario.

- (void)layoutIfNeeded

discusión Utilizar este método para obligar a la disposición de subvistas antes de dibujar.

Disponibilidad Disponible en el iPhone OS 2.0 y posterior.

Al migrar una aplicación OpenGL SDK de 3 a 4, layoutSubviews no fue llamado nunca más. Después de mucho ensayo y error, finalmente abrí MainWindow.xib, seleccionado el objeto de ventana, en el inspector eligió Ventana ficha Atributos (más a la izquierda) y se comprueba "visible en el lanzamiento". Parece que en SDK 3 que todavía se utiliza para causar una llamada layoutSubViews, pero no en 4.

6 horas de frustración ponen a su fin.

Un caso bastante oscura, pero potencialmente importante cuando layoutSubviews nunca se ha llamado es:

import UIKit

class View: UIView {

    override class var layerClass: AnyClass { return Layer.self }

    class Layer: CALayer {
        override func layoutSublayers() {
            // if we don't call super.layoutSublayers()...
            print(type(of: self), #function)
        }
    }

    override func layoutSubviews() {
        // ... this method never gets called by the OS!
        print(type(of: self), #function)
    }
}

let view = View(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top