ios - puede - ¿Cómo puedo cambiar la prioridad de las restricciones en tiempo de ejecución?
restricciones iphone 4 intentos fallidos (7)
Ahora puede hacerlo, simplemente tome la conexión IBOutlet para sus restricciones, luego use este código.
self.webviewHeight.priority = UILayoutPriority(rawValue: 1000)
Tengo una vista que tiene altura dinámica y estoy tratando de cambiar esta prioridad de altura de vista en tiempo de ejecución.
Aquí está mi parte del código;
if (index == 0) {
surveyViewHeightConstraint.constant = 0;
surveyViewHeightConstraint.priority = 1000;
} else if (index == 1) {
surveyViewHeightConstraint.constant = 163;
surveyViewHeightConstraint.priority = 500;
}
Estoy cambiando el índice con una acción de botón. Cuando ejecuto este código, recibo este error:
*** Assertion failure in -[NSLayoutConstraint setPriority:], /SourceCache/Foundation/Foundation-1141.1/Layout.subproj/NSLayoutConstraint.m:174
¿Cuál es mi error aquí?
Como se indica en
la referencia de clase
NSLayoutConstraint
:
Las prioridades no pueden cambiar de no requerido a requerido, o de requerido a no requerido. Se generará una excepción si una prioridad de
NSLayoutPriorityRequired
en OS X oUILayoutPriorityRequired
en iOS se cambia a una prioridad más baja, o si se cambia una prioridad más baja a una prioridad requerida después de agregar las restricciones a una vista. Se permite cambiar de una prioridad opcional a otra prioridad opcional incluso después de instalar la restricción en una vista.
Use la prioridad 999 en lugar de 1000. No será absolutamente necesario técnicamente hablando, pero será una prioridad más alta que cualquier otra cosa.
De acuerdo con la
NSLayoutConstraints class
UIKit Module
dentro del
UIKit Module
Si el nivel de prioridad de una restricción es menor que UILayoutPriorityRequired, entonces es opcional. Las restricciones de mayor prioridad se cumplen antes que las restricciones de menor prioridad. La satisfacción de la restricción no es todo o nada. Si una restricción ''a == b'' es opcional, eso significa que intentaremos minimizar ''abs (ab)''. Esta propiedad solo puede modificarse como parte de la configuración inicial o cuando sea opcional. Después de agregar una restricción a una vista, se generará una excepción si la prioridad se cambia de / a NSLayoutPriorityRequired.
Ejemplo: - Restricciones de
UIButton
con varias prioridades -
func setConstraints() {
buttonMessage.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: buttonMessage, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: -10).isActive = true
let leading = NSLayoutConstraint(item: buttonMessage, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 10)
leading.isActive = true
let widthConstraint = NSLayoutConstraint(item: buttonMessage, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100)
let heightConstraint = NSLayoutConstraint(item: buttonMessage, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 50)
let trailingToSuperView = NSLayoutConstraint(item: buttonMessage, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0)
trailingToSuperView.priority = 999
trailingToSuperView.isActive = true
//leading.isActive = false//uncomment & check it will align to right of the View
buttonMessage.addConstraints([widthConstraint,heightConstraint])
}
Espero que este escenario ayude a alguien: tenía dos restricciones, que eran opuestas entre sí, es decir, no podían satisfacerse al mismo tiempo, en el generador de interfaces, uno de ellos tenía 1000 prioridades y el otro tenía menos de 1000. cuando los cambié en el código, tuve este error:
Finalización de la aplicación debido a la excepción no detectada ''NSInternalInconsistencyException'', razón: ''No se admite la mutación de una prioridad de requerida a no en una restricción instalada (o viceversa). Pasaste la prioridad 250 y la prioridad existente era 1000. ''
luego los inicialicé en la función viewDidLoad con los valores .defaultHigh y .defaultLow y esto solucionó mi problema.
La forma en que siempre hemos manejado esto es no cambiando la constante de restricción, solo la prioridad. Por ejemplo, en su situación tenga dos restricciones de altura.
heightConstraintOne (who''s height is set in the storyboard at 150, and priority set at 750)
heightConstraintTwo (who''s height is set in the storyboard at 0, and priority set at 250)
si desea ocultar la vista, usted:
heightConstraintTwo.priority = 999;
Del mismo modo, si desea mostrar la vista:
heightConstraintTwo.priority = 250;
Quiero hacer una pequeña adición a la respuesta de Cyrille.
Si está creando una restricción en el código, asegúrese de establecer su prioridad antes de activarla. Por ejemplo:
surveyViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.superview
attribute:NSLayoutAttributeHeight
multiplier:1
constant:0];
surveyViewHeightConstraint.active = YES;
surveyViewHeightConstraint.priority = 999;
Esto daría lugar a una excepción en tiempo de ejecución.
No se admite la mutación de una prioridad de requerida a no en una restricción instalada (o viceversa).
El orden correcto es:
surveyViewHeightConstraint.priority = 999;
surveyViewHeightConstraint.active = YES;
Versión rápida:
myContraint.priority = UILayoutPriority(999.0)