Autolayout no parece funcionar al cambiar las dimensiones de vista de forma programática

Tengo una subclass personalizada de UITableViewCell con algunas restricciones establecidas.

El problema es cuando trato de cambiar el tamaño de una vista como esta:

CGRect frm = CGRectMake(0, 0, someValue, 30); cell.indentView.frame = frm; 

otras vistas, que dependen del ancho cell.indentView, no se mueven en absoluto.

¿Qué puede ser el caso?

Este código funcionará:

 // enumerate over all constraints for (NSLayoutConstraint *constraint in cell.indentView.constraints) { // find constraint on this view and with 'width' attribute if (constraint.firstItem == cell.indentView && constraint.firstAttribute == NSLayoutAttributeWidth) { // increase width of constraint constraint.constant = someValue; break; } } 

Es porque no puede simplemente cambiar el marco de un object que tiene limitaciones de autolayout (porque las restricciones dictan las ubicaciones, no establecen manualmente frame properties del frame … las properties del frame se restablecerán a medida que se reaplicen las restricciones). Vea esta publicación sueltamente relacionada en la que se demuestra cómo ajustar correctamente una restricción para mover una vista. (En ese caso, estamos animando, que no es el problema aquí, pero sí demuestra cómo se ajusta una restricción para efectuar el movimiento de una UIView ).

En resumen, si desea mover una vista UIView dentro de la reproducción automática, no debe intentar cambiar el frame , sino ajustar las restricciones mismas. Esto se simplifica si crea references de IBOutlet para las propias restricciones, en ese punto, puede ajustar la constant de NSLayoutConstraint .


Actualizar:

Egor recomendó enumerar las restricciones y editar la que coincidía con la una en cuestión. Eso funciona muy bien, pero personalmente, prefiero tener un IBOutlet para la restricción específica que quiero editar en lugar de enumerarlos y search el que está en cuestión. Si tuviera una IBOutlet denominada indentViewWidthConstraint para el ancho NSLayoutConstraint de la indentView , podría simplemente:

 self.indentViewWidthConstraint.constant = newIndentConstantValue; 

Tendrá que decirle al marco que actualice, por ejemplo, llamando a setNeedsLayout , setNeedsUpdateConstraints o layoutIfNeeded . Consulte la documentation de UIView para ver el uso adecuado.