Restricción iOS "UITemporaryLayoutHeight"

Estoy usando systemLayoutSizeFittingSize para get el tamaño más pequeño para una subclass de vista personalizada que satisfaga sus restricciones internas.

 let someView = SomeView() someView.setNeedsUpdateConstraints() someView.setNeedsLayout() someView.layoutIfNeeded() let viewSize = someView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) println(viewSize) // PRINTS (0.0, 96.0) WHICH IS RIGHT! 

Obtengo el valor correcto pero también obtengo un Unable to simultaneously satisfy constraints :

 "<NSLayoutConstraint:0x7ff16b753190 '_UITemporaryLayoutHeight' V:[ProjectName.SomeView:0x7ff16b772210(0)]>", "<NSLayoutConstraint:0x7ff16b75de50 UIImageView:0x7ff16b76eff0.top == ProjectName.SomeView:0x7ff16b772210.topMargin>", "<NSLayoutConstraint:0x7ff16b7653f0 UIImageView:0x7ff16b76eff0.bottom <= ProjectName.SomeView:0x7ff16b772210.bottomMargin>" 

A continuación se muestra mi subclass SomeView SomeView.

Simplemente contiene una image de 80×80 fijada a los márgenes superior, izquierdo y inferior. (Estoy usando PureLayout para escribir restricciones).

Ahora, obviamente, esta vista tendrá una altura fija de 96 (80 + 8×2 para los márgenes), pero teóricamente podría estirarse si sus subvendas cambiaron de tamaño.

¿Algunas ideas? Buscando google para UITemporaryLayoutHeight (o Ancho) da 0 resultados …

 class SomeView: UIView { let imageView = UIImageView() var constraintsSet = false override init(frame: CGRect) { super.init(frame: frame) backgroundColor = UIColor.lightGrayColor() imageView.backgroundColor = UIColor.darkGrayColor() addSubview(imageView) } override func updateConstraints() { if(!constraintsSet) { imageView.autoPinEdgeToSuperviewMargin(.Top) imageView.autoPinEdgeToSuperviewMargin(.Left) imageView.autoPinEdgeToSuperviewMargin(.Bottom, relation: NSLayoutRelation.GreaterThanOrEqual) imageView.autoSetDimension(.Width, toSize: 80.0) imageView.autoSetDimension(.Height, toSize: 80.0) constraintsSet = true } super.updateConstraints() } } 

Esta:

Simplemente contiene una image de 80×80 clavada en los márgenes superior, izquierdo y inferior.

y esto

NSLayoutConstraint: 0x7ff16b753190 '_UITemporaryLayoutHeight' V: [ProjectName.SomeView: 0x7ff16b772210 (0)]

es la fuente del problema. UIKit está en algún punto del process de carga / layout / visualización usando una altura de 0. Dado que tiene restricciones para la parte superior e inferior y que imageview tiene su tamaño de contenido intrínseco, le está diciendo que se ajuste a la image en un espacio vertical cero.

La forma habitual de resolver esto es establecer la prioridad de la restricción superior o inferior a cualquier valor inferior a 1000.

Me he dado count de que esto me sucede si llamo layoutIfNeeded en una vista antes de que se haya distribuido a los padres. Apuesto a que si someView.layoutIfNeeded() ya no someView.layoutIfNeeded() ese error. Probablemente también podrías deshacerte de someView.setNeedsLayout() y replacelo con someView.updateConstraintsIfNeeded() . systemLayoutSizeFittingSize no debería requerir que las vistas estén realmente diseñadas, solo necesita que las restricciones se configuren correctamente.

Tuve esta advertencia cuando la vista no tiene una vista de superview y se llama a layoutIfNeeded . Mi solución fue llamar a layoutIfNeeded después de layoutIfNeeded la vista en una vista de superview . Espero que esto ayude:

 - (void)didMoveToSuperview { [super didMoveToSuperview]; [self layoutIfNeeded]; } 

El lugar donde está agregando las restricciones parece ser la fuente de su problema.

Además, debe establecer setTranslatesAutoresizingMaskIntoConstraints(false) en imageView

Intente agregar las restricciones cuando agregue la image como subvista.

Algo así debería funcionar:

 class SomeView: UIView { let imageView = UIImageView() var constraintsSet = false override init(frame: CGRect) { super.init(frame: frame) backgroundColor = UIColor.lightGrayColor() imageView.backgroundColor = UIColor.darkGrayColor() addSubview(imageView) // Don't forget this imageView.setTranslatesAutoresizingMaskIntoConstraints(false) imageView.autoPinEdgeToSuperviewMargin(.Top) imageView.autoPinEdgeToSuperviewMargin(.Left) imageView.autoPinEdgeToSuperviewMargin(.Bottom, relation: NSLayoutRelation.GreaterThanOrEqual) imageView.autoSetDimension(.Width, toSize: 80.0) imageView.autoSetDimension(.Height, toSize: 80.0) } } 

Espero que este trabajo. ¡Dejame saber si necesitas mas ayuda!