translatesautoresizingmaskintoconstraints ios autolayout nslayoutconstraint

ios - translatesautoresizingmaskintoconstraints - ¿Qué es_UITemporaryLayoutWidth y por qué rompe mis restricciones?



swift constraints programmatically (8)

Tengo un guión gráfico con Autolayout y Clases de tamaño. Diseño bastante complicado, y desafortunadamente no puedo precisar cómo reproducir el problema en un nuevo proyecto.
Pero la vista en cuestión está anclada en el borde izquierdo y derecho de la pantalla con una restricción que tiene prioridad 750 (es decir, |-(0@750)-[myView]-(0@750)-| , además, tiene una mayor o igual que la restricción con una prioridad de 1000 (es decir, |-(>=0)-[myView]-(>=0)-| ). Esto se hace para limitar el ancho en un iPad, por lo que hay una restricción de ancho de width <= 600 @1000 , y un centro horizontal en la restricción del contenedor . Además de eso, la vista tiene una restricción de relación de aspecto de 3: 1. Como dije, bastante complicada.

Interface Builder no muestra ningún problema con las restricciones. La vista previa del diseño de Xcode es correcta para todos los dispositivos.

Cuando ejecuto la aplicación, iOS me dice que tiene restricciones conflictivas.

Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don''t want. Try this: (1) look at each constraint and try to figure out which you don''t expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you''re seeing NSAutoresizingMaskLayoutConstraints that you don''t understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0x7fd72853ff80 DMXKit.DipSwitchAssembly:0x7fd72990d0e0.width == 3*DMXKit.DipSwitchAssembly:0x7fd72990d0e0.height>", "<NSLayoutConstraint:0x7fd728574e50 ''_UITemporaryLayoutWidth'' H:[DMXKit.DipSwitchAssembly:0x7fd72990d0e0(400)]>", "<NSLayoutConstraint:0x7fd72856e9c0 V:[DMXKit.DipSwitchAssembly:0x7fd72990d0e0(133)]>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7ffb19798000 DMXKit.DipSwitchAssembly:0x7ffb1979a000.width == 3*DMXKit.DipSwitchAssembly:0x7ffb1979a000.height>

Esto se repite un par de veces, con las mismas restricciones exactas (es decir, el mismo puntero). Eso también es extraño, parece que la restricción no está realmente rota. Cuando se ejecuta, la aplicación se ve 100% correcta. Cuando miro la aplicación en el depurador de vista de Xcode, la restricción con la dirección 0x7ffb19798000 sigue ahí, por lo que nunca se rompió.

¿ _UITemporaryLayoutWidth dónde viene el _UITemporaryLayoutWidth constaint? Obviamente no lo agregué. Google no escupe nada útil sobre _UITemporaryLayoutWidth . ¿Alguien encontró un problema como este?


Como se mencionó anteriormente, las restricciones temporales parecen establecerse en vistas que no tienen una vista primaria. Encontré que asegurar que tradysAutoresizingMaskIntoConstraints sea false en la vista de nivel superior eliminó las restricciones temporales. Como:

topView.translatesAutoresizingMaskIntoConstraints = false


En mi caso, el problema fue el siguiente:

He creado un UIButton .
Establecí sus restricciones de ancho y altura.
Agregué el botón a su supervisión.
Puse sus restricciones de diseño superior y superior a la supervisión.

Esto creó el error " Unable to simultaneously satisfy constraints " y una de las restricciones en conflicto fue _UITemporaryLayoutHeight .

Cuando agregué el botón a su superview antes de establecer sus restricciones de ancho y altura, el error desapareció.


En mi situación, solo obtuve este conflicto UITemporaryLayoutWidth en esta situación 1 creo una vista con [UIView nuevo], y no la agregué a ninguna vista de supervisión 2, entonces creo una restricción de ancho para esta vista que se acaba de crear 3 invocar layoutIfNeded to Esta vista de inmediato, y el conflicto ocurre.

por lo tanto, la forma de eliminar este error es simple: no llame a layoutIfNeeded it self antes de agregarlo a alguna supervisión.


La raíz del problema es la relación de aspecto 3: 1. Si lo cambio a otra cosa, funciona, ahora uso 4:1.4 , que funciona. No sé por qué, pero funciona.

No sé mucho sobre los aspectos internos del diseño automático, pero creo que el problema es el orden en el que el motor de diseño desea cumplir con las restricciones. Las clases de tamaño pueden ser la razón por la cual se agrega la restricción de ancho temporal.

Las restricciones no satisfactorias no parecen ser un problema real porque parece que son insatisfiables solo temporalmente. Es solo un par de líneas de registro que aparecen cada vez que se crea la vista.


Mi problema con el límite temporal de la UIT era que estaba creando botones programáticamente y la restricción de tempWidth estaría alrededor de 0.1 de mi restricción de ancho. (Aunque molesto, esto solo sucedió al crear botones en una de las múltiples formas en que creé los botones)

El problema era que estaba usando .adjustsFontSizeToFitWidth = true para el título del botón.

Comenté esa línea y se fue.


Pasé un par de horas en este problema hoy. Estaba configurando el modo de contenido de mi UIButton imageView inmediatamente después de inicializar el elemento, que parecía forzar un diseño antes de configurar las restricciones en mi clase de nivel superior (que incluía la restricción de la altura / anchura).


Por lo tanto, no estoy seguro de si esto te ayuda con tu problema, ya que parece que estás construyendo tu diseño en IB, pero hay un problema que acabo de encontrar y que puede ayudar a otros a buscar Google "_UITemporaryLayoutWidth".

Mi situación era que estaba agregando restricciones de diseño automático durante el inicio y estaba activando accidentalmente un ''diseño de necesidades'' antes de agregar la vista a la jerarquía de vista (modificar el diseño de los activadores de bordes de botones). Parece que el sistema agrega estas restricciones temporales y (¿Supongo?) Las elimina después de agregar la vista a la jerarquía. Las restricciones temporales establecen 0 dimensiones (en mi caso) que pueden fallar si usted, por ejemplo, establece valores constantes de restricción específicos en su diseño (por ejemplo, quiere 16px entre estos botones pero hay 0 espacios en esa dimensión ...)

Actualización: se investigó un poco más y se encontró que la restricción temporal parece corresponder con el marco que se usa para inicializar la vista principal. En mi caso, el marco que utilicé era de tamaño 0x0, por lo que la restricción de temperatura se evaluó en relación con el tamaño de 0x0, por lo que falla. Verifiqué que si inicio con un marco de 5x5, veo el mismo error con la restricción _UITemporaryLayoutWidth (5). La otra cosa que he notado es que la restricción parece agregarse y eliminarse durante la evaluación del diseño. Si me rompo justo antes de activar el diseño y analizar las restricciones, no veo las restricciones de temperatura. Tampoco veo las restricciones después del error, así que sospecho que sintetizan las restricciones temporales, las agregan, las resuelven y luego las eliminan.

Actualización 2: Ok, tal vez esto sea TMI pero esto podría ser de alguna utilidad para alguien. Mi idea actual es que estas restricciones temporales son un vistazo a cómo el sistema maneja la manipulación de fotogramas mixtos y la reproducción automática dentro de una única jerarquía de vistas. En mi caso, mi vista no tenía padre y no tenía restricciones que definieran su tamaño, pero sí tenía un marco cero, lo que significaba que el sistema asumía que era el tamaño que debía usar al resolver el diseño. Mi pensamiento es que el sistema sintetiza estas restricciones temporales para las vistas que tienen sus marcos establecidos explícitamente para resolver el resto del sistema a medida que atraviesa la jerarquía.

Actualización 3: Entonces, me encontré con este problema de nuevo y quería compartir un poco más de información. Mi situación era que estaba tratando de medir esencialmente las vistas que no tenían padres utilizando el método systemLayoutSizeFittingSize :. En pocas palabras, tuve que llamar a layoutIfNeded en la vista antes de medirla. Aquí es donde me encuentro con el conflicto con las restricciones temporales, ya que la vista no tiene una vista de supervisión. Las constantes de restricción de temperatura (las dimensiones) se corresponden con el cuadro que se establece en la vista sin una vista de supervisión. Creo que esto tiene sentido (sin embargo, establecer un cuadro en una vista que se va a usar con AutoLayout parece extraño). .) Pude evitar el problema de restricción temporal diciendo: si la vista no tiene una vista de supervisión, agréguela a una vista de supervisión temporal; medida; eliminarlo de la supervisión temporal. Espero que esto sea útil.


Solo una rápida adición a los comentarios anteriores, la solución simple que funcionó para mí fue cambiar el orden en que se creaban mis restricciones. Estaba creando restricciones programáticas tanto en las vistas como en las vistas de supervisión, pero estaba haciendo las vistas antes de las vistas de supervisión. Así que lo cambié para que las restricciones de supervisión fueran las primeras, luego se agregaron las subvistas, lo que significaba que ya no era necesario llamar a _UITemporaryLayoutWidth, por lo que los problemas de restricción desaparecieron.