Autoajustar cómo get el valor calculado de la vista

Hay una cosa que realmente me está volviendo loco por el layout automático, estoy haciendo mis testings y descubrí que si subclasss una UIView y pones algunas vistas con sus restricciones es imposible saber el valor calculado.
No digamos que tenemos una TestViewClass que henetworkinga de UIView , tenemos algunas subvistas dentro. Queremos usarlo para iPhone e iPad, por lo que utilizamos dos tamaños, supongamos 100×100 y 200×200, hicimos nuestras limitaciones para que todo funcione. Construimos esta vista colocando esas subvistas en algunas posiciones.
Ahora necesitamos build otras subvistas que contengan una cantidad de botones como subvistas (contentView), qué número se entrega en time de ejecución.
El algorithm seleccionará el tamaño de esta vista de contenido y pondrá la cantidad correcta de botones calculando el espacio entre ellos de manera tal que esté a la misma distancia entre sí pero cubriendo todo el ancho de la vista de contenido. Por ejemplo, el contenido de la vista es de 200 puntos de ancho, los botones son 3 y están al cuadrado con un lado de 60. Juntos cubren 180, por lo tanto, tenemos 20 puntos a la izquierda que deben colocarse como un espacio entre los botones-> 10 puntos.
Eso es bastante fácil, hecho miles de veces antes del layout automático. Para hacer eso necesito el ancho de la vista de contenido que tiene algunas restricciones a su vista de supervisión que hacen que se networkingimensione su ancho de acuerdo con el tamaño de la vista de supervisión, el problema es que no puedo encontrar ningún lugar dentro de la implementación de UIView donde puedo get el valor final de el tamaño de la vista de contenido.
Intenté ver -layoutSubviews , -updateConstraints , -didMoveToSuperview , show de valores son siempre el original. ¿Cuándo se calculan los nuevos cuadros?
Claramente no obtuve nada sobre el layout automático …

Descubrí este problema tratando de establecer la altura de la celda de vista de tabla, tratando de hacer que aparezcan todos en la pantalla de forma independiente según el tamaño de la vista de tabla. aquí está la pregunta relacionada otra pregunta

Finalmente, obtuve lo que me faltaba sobre el layout automático y es un concepto fundamental.

Autolayout no funciona como autorizar máscaras, los nuevos frameworks no se actualizan instantáneamente, sino por request.

Esto hace una gran diferencia, parece estar sincronizado con el ciclo de renderización de CATransaction, que tiene sentido, porque el cálculo del layout podría ser una tarea costosa y es inútil hacerlo hasta que realmente lo necesite, la mayoría de las veces durante la renderización.
Por supuesto, hay pocas excepciones, como esta y ¿cómo podemos forzar el layout automático para realizar este cálculo? podemos hacer setting -setNeedsLayout method y -layoutIfNeeded . el primer método marca la vista como "sucia" y la segunda fuerza un layout inmediato. Si configura llamar a esos dos methods en -didMoveToSuperview justo después de get los cuadros actualizados correctos.
Espero que esto ayude, Andrea

Puede usar view viewDidLayoutSubviews del controller de viewDidLayoutSubviews , que le notificará cuando se viewDidLayoutSubviews las vistas. Si todo esto está agregando restricciones está sucediendo en una UIView personalizada, simplemente podría escribir un método para su vista llamada viewDidLayoutSubviews y hacer que el controller de vista lo llame cuando el controller de vista lo reciba. En este punto, los contenedores deben tener sus dimensiones debidamente configuradas.

Pero, hay un par de enfoques que incluso espacian un grupo de botones sin tener que preocuparse por saber el tamaño de la vista del contenedor:

  1. Un enfoque que he usado para espaciar los controles en un contenedor es crear lo que llamo vistas "espaciadoras" (vistas que están presentes, pero solo tienen un background clearColor , por lo que no puedes verlas visualmente). A continuación, puede crear una serie de restricciones utilizando, de manera efectiva, algo como:

     H:|[spacer1][button1(60)][spacer2(==spacer1)][button2(60)][spacer3(==spacer1)][button3(60)][spacer4(==spacer1)]| 

    Si su número de botones es fijo, puede hacer esto en un único constraintsWithVisualFormat , como el anterior. Si se trata de una cantidad variable de botones, puede recorrerlos a través de ellos, creando una secuencia VFL para cada par de botones y espaciadores (por ejemplo, el primer button usaría VFL de

     H:|[spacer][button(60)] 

    todos los siguientes crearían otro button y otro espaciador y usarían el siguiente VFL:

     H:[previousButton][spacer(==originalSpacer)][button(60)] 

    y luego agrego un espaciador final al final:

     H:[lastButton][spacer(==originalSpacer)]| 

    Esto es un poco engorroso, pero como puede ver, sus controles están perfectamente distribuidos, espaciados uniformemente, y nunca necesita saber las dimensiones del contenedor.

  2. Otro enfoque es usar el atributo NSLayoutFormatAlignAllCenterX . Esto pasa por alto la necesidad de crear todos esos espaciadores, pero si usa un algorithm simple como lo hago a continuación, los centros se distribuirán de manera uniforme entre ellos. Por lo tanto, además de las restricciones verticales estándar y la restricción de anchura horizontal para el button, puede controlar la colocación horizontal de los botones con:

     [containerView addConstraint:[NSLayoutConstraint constraintWithItem:button[i] attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:containerView attribute:NSLayoutAttributeCenterX multiplier:2.0 * (double) (i + 0.5) / (double) n constant:0.0]]; 

    donde i es el índice basado en cero de qué button estás configurando esta restricción horizontal y n es el número de botones.