¿Cómo puedo obtener una vista actual de la anchura y la altura cuando se utiliza el diseño automático limitaciones?

No estoy hablando acerca de la propiedad de marco, porque a partir de que sólo se puede obtener el punto de vista del tamaño de la xib. Estoy hablando de cuando la vista se cambia el tamaño a causa de sus limitaciones (tal vez después de una rotación, o en respuesta a un evento). Es allí una manera de conseguir su anchura y altura actual?

Traté de recorrer sus limitaciones buscando la anchura y la altura de las limitaciones, pero que no es muy limpio y falla cuando hay limitaciones intrínsecas (ya que no puede diferenciar entre los dos). También, que sólo funciona si realmente tienen la anchura y la altura de las limitaciones, que no se si dependen de otras restricciones para cambiar el tamaño.

¿Por qué es tan difícil para mí. ARG!

  • Yo habría pensado que el punto de vista de los límites en cualquier momento, celebró su anchura y altura actual. Esto es lo que consigue ajustar durante el proceso de diseño.
  • Hmm, nunca pensé comprobar los límites. Voy a hacerlo ahora.
InformationsquelleAutor yuf | 2012-11-19

5 Kommentare

  1. 238

    La respuesta es [view layoutIfNeeded].

    He aquí por qué:

    Usted todavía puede disfrutar de la vista actual de la anchura y la altura por la inspección de view.bounds.size.width y view.bounds.size.height (o el marco, el cual es equivalente a menos que usted está jugando con el view.transform).

    Si lo que quieres es la anchura y la altura implícita por sus limitaciones existentes, la respuesta no es inspeccionar las restricciones de forma manual, ya que requiere volver a aplicar la totalidad de la restricción de la resolución de la lógica de la auto sistema de diseño. En su lugar, lo que debes hacer es simplemente preguntar diseño automático de actualización de diseño, de modo que los que resuelve las limitaciones y actualiza el valor de la vista.los límites con la solución correcta y, a continuación, inspeccione la vista.límites.

    ¿Cómo se puede pedir de diseño auto actualización del diseño? Llame [view setNeedsLayout] si desea diseño automático de actualizar el diseño en el siguiente turno de ejecutar el bucle.

    Sin embargo, si usted desea actualizar el diseño de inmediato, así que usted puede acceder de inmediato a los nuevos límites de valor más adelante dentro de su función actual, o en otro momento, antes de la vuelta de la ejecución del bucle, entonces usted necesita para llamar a [view setNeedsLayout] y [view layoutIfNeeded].

    Usted hizo una segunda pregunta: «¿cómo puedo cambiar la altura y la anchura de restricción si no tengo una referencia a él directamente?».

    Si usted cree que la restricción en el IB, la mejor solución es crear un IBOutlet en su vista o controlador de la vista de modo que usted no tiene una referencia directa a él. Si usted crea la restricción en el código, entonces usted debe aferrarse a una referencia en una interna débil de la propiedad en el momento cuando se creó. Si alguien crea la restricción, entonces usted necesita para encontrar mediante el examen el examen de la vista.limitaciones de la propiedad en la vista, y posiblemente de toda la vista de la jerarquía, y la aplicación de la lógica que se encuentra la crucial NSLayoutConstraint. Este es probablemente el camino equivocado, ya que también se requiere efectivamente usted para determinar cual de restricción determina los límites de tamaño, cuando no hay garantía de una respuesta simple a esa pregunta. El final de los límites de valor podría ser la solución a un sistema muy complicado de múltiples restricciones, con múltiples prioridades, etc., de modo que no hay una única restricción es la «causa» del valor final.

    • Un excelente respuesta y bien explicado, también. Me salvó después de una hora o dos de tirarme de los pelos.
    • layoutIfNeeded es grande, y va a hacer que el marco disponible de inmediato. Sin embargo, también la fuerza de la representación de las restricciones en todos los puntos de vista de los sub-árboles de la vista sobre la que está llamado. Si usted está agregando puntos de vista mediante programación, por ejemplo, y llame a layoutIfNeeded en todos ellos en su rutina recursiva, usted puede encontrar que su jerarquía hace muy lentamente. (Esto lo aprendí de la manera difícil) Como se mencionó en la excelente respuesta», setNeedsLayout` es más eficiente y hacer que el marco disponible en la siguiente fase de diseño, que, idealmente, ocurre en aproximadamente 1/60 de segundo.
    • Sé que esto es viejo, pero ¿dónde se llame a este método? En initWithCoder?
    • En mi experiencia, cada vez sería más seguro para establecer directamente los marcos dentro de una vista subvistas, también puede establecer indirectamente los marcos obligando a los principios de diseño automático con layoutIfNeeded. AL sistema puede ser opaco, pero esencialmente es sólo hacer matemáticas en layoutSubviews y utilizar los resultados para hacer un montón de setFrame: llamadas. Así que usted puede utilizar esta técnica en cualquier momento después de que las restricciones están instalados. (Si va a cargar a partir de un guión gráfico o xib, que en awakeFromNib no initWithCoder.) Pero me gustaría probar a usarlo tan tarde como sea posible, para estar seguro.
    • Bueno, creo que te amo. Yo no tenía idea de cuál es el propósito de setNeedsLayout o setNeedsDisplay fue. Yo estaba luchando con la obtención de la nueva presentación de la actualización y teniendo a los peces por la altura de mi objeto y especificar la anchura y la altura. Gracias, gracias, gracias.
    • ¿Por qué la fuerza de la disposición sólo para obtener los límites? Esto parece ineficiente y con una interfaz compleja esta situación es potencialmente va a ser costoso. En lugar de acceder a los últimos límites de la viewDidLayoutSubviews o incluso viewWillLayoutSubviews y dejar de cacao manejar su propio diseño de temporización. Establecer una propiedad si usted necesita para tener acceso al valor o la bandera de evitar múltiples llamadas si que es un problema.
    • Sí, sólo necesita de la fuerza de diseño si usted necesita el acceso a la de diseño auto-valor calculado antes de la vuelta de la ejecución del bucle – por ejemplo, dentro de la medida de la corriente llamada a la función.
    • Este tipo de respuesta, insiste en que el usuario (us) de este motor de renderizado (UIKit) debe asumir la responsabilidad de la representación de sí mismo. Firmemente creo que no es correcto. El uso de algo como viewDidLayoutSubviews debe ser el mejor en la mayoría de los casos y similares alertas cada vez que algo cambia en la pantalla debe ser utilizado en su lugar.
    • Buen punto — si usted no necesita el valor de tamaño inmediatamente, es mejor esperar para el normal de diseño y a continuación acceder a el tamaño de dentro de viewDidLayoutSubviews. Pero esta cuestión de manera explícita preguntando acerca de cómo obtener el tamaño implícita una visión del corriente restricciones. Espera hasta que viewDidLayoutSubviews incendios significa que usted obtiene el tamaño implícita no por las limitaciones actuales, pero por las restricciones después de que el diseño se completa, y esto significa que usted no obtener la respuesta hasta que sucede. Que a menudo es lo suficientemente bueno, pero no es bastante lo que se les pide.
    • «Si usted crea la restricción en el código, entonces usted debe aferrarse a una referencia en una interna débil bienes en el momento en que lo creó» ¿por qué debería ser débil?
    • Debido a la adición de la restricción a la vista de la causa el ver a retener (o tal vez para conservar la vista), así que usando una débil propiedad de asegurarse de que el controlador de vista no incorrectamente aferrarse a la restricción si la vista se ha eliminado
    • En mi caso, que tratando de actualizar mi vista personalizada de todo tamaño con diferentes tamaños de los dispositivos, la línea funcionó a la perfección! thx
    • «actualización del diseño de inmediato…, entonces usted necesita llamar [view setNeedsLayout] y [view layoutIfNeeded]« — me estoy encontrando que sólo [view layoutIfNeeded] es necesario.
    • será suficiente si ya has hecho alguna acción que invita implícitamente setNeedsLayout. Pero haciendo tanto es una buena práctica ya que se trabajará, si desea forzar diseño incondicionalmente.
    • No funciona si necesita acceder a el tamaño de un niño de la vista, en el fondo en la vista de jerarquía. Solicitando diseño se asegura de que toda la jerarquía se actualiza.

  2. 8

    Tuve un problema similar en el que necesitaba para agregar un borde superior e inferior para un UITableView que cambia de tamaño basado en sus limitaciones de instalación en el UIStoryboard. Yo era capaz de acceder a la versión actualizada de las restricciones con - (void)viewDidLayoutSubviews. Esto es útil para que usted no necesita una subclase de la vista y anular su método de diseño.

    /*** SET TOP AND BOTTOM BORDERS ON TABLE VIEW ***/
    - (void)addBorders
    {
        CALayer *topBorder           = [CALayer layer];
        topBorder.frame              = CGRectMake(0.0f, self.tableView.frame.origin.y, 320.0f, 0.5f);
        topBorder.backgroundColor    = [UIColor redColor].CGColor;
    
        CALayer *bottomBorder        = [CALayer layer];
        bottomBorder.frame           = CGRectMake(0.0f, (self.tableView.frame.origin.y + self.tableView.frame.size.height), 320.0f, 0.5f);
        bottomBorder.backgroundColor = [UIColor redColor].CGColor;
    
        [self.view.layer addSublayer:topBorder];
        [self.view.layer addSublayer:bottomBorder];
    }
    
    /*** GET AUTORESIZED FRAME DIMENSIONS ***/
    - (void)viewDidLayoutSubviews{
        [self addBorders];
    }

    Sin llamar al método de la viewDidLayoutSubview método, sólo el borde superior se dibuja correctamente, como el borde inferior está en algún lugar fuera de la pantalla.

    • Este parece que han hecho por mí, gracias!
    • viewDidLayoutSubviews ser llamado un par de veces, se crea toneladas de capas… es necesario agregar algunas existencia de controles antes de la adición de otro de la capa.
    • Comentario de algunos años de retraso… también debe llamar a este método en la superclase cuando se reemplaza antes de nada: [super viewDidLayoutSubviews];
  3. 4

    Para aquellos que aún pueden estar frente a dichos problemas, especialmente con TableviewCell.

    Sólo reemplazar el método:

    -(void)layoutSubviews
    {
    //your code here like drawing a shadow
    }

    En caso de UITableViewCell o UICollectionViewCell crear una subclase de la célula y anular el mismo método:

    -(void)layoutSubviews
    {
    //your code here like drawing a shadow
    }
    • esta es la única manera de conseguir el verdadero tamaño final de mi punto de vista
  4. 3

    Uso -(void)viewWillAppear:(BOOL)animated y llame a [self.view layoutIfNeeded]; – funciona he probado.

    porque si usted utiliza -(void)viewDidLayoutSubviews funcionará sin duda, pero este método es llamado cada vez que su interfaz de usuario demandas updations/cambios. Que tendrán que ser difícil de manejar. Tecla de función se utiliza una variable de tipo bool para evitar tales bucle de llamadas. mejor uso viewWillAppear. Recuerde viewWillAppear también se llama a si se carga la vista atrás de nuevo (sin reasignación).

  5. 2

    El marco sigue siendo válida. En el final, el punto de vista usa su propiedad de marco para poner a sí mismo. Se calcula que, basados en cuadros de todas las restricciones. Las restricciones sólo se utilizan para la disposición inicial (y en cualquier momento layoutSubviews es llamada en una vista como después de una rotación). Después de eso, la posición de la información en el marco de la propiedad. O está usted viendo de otra manera?

    • Estoy viendo de otra manera. El marco de los valores no cambian, incluso después de cambiar la anchura/altura restricciones directamente (mediante el cambio de sus constantes. Tengo un IBOutlet a ellos en el xib)
    • Ha cambiado de y llamado needsLayout derecho?
    • Mi problema es único porque puedo cambiar la restricción, entonces la necesidad de utilizar la estructura de la misma función. Llamar setNeedsLayout no se actualiza inmediatamente. Supongo que tengo que esperar a que el diseño de la primera, a continuación, utilice el cuadro. Mi segunda pregunta es, ¿cómo puedo cambiar la altura y la anchura de restricción si no tengo una referencia a él directamente?
    • Usted debe dispatch_async entonces, y le permite retrasar su código hasta el siguiente fotograma. En cuanto a la segunda parte…no sé…tendría que recorrer todas las limitaciones y buscar lo que uno es aplicable…IBOutlets son mucho más fáciles.
    • Cierto para IBOutlets, pero quiero escribir una función en una categoría para un UIView que no tengo el Sii para trabajar con.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea