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 la acción de un botón. Cuando ejecuto este código, obtengo este error:
*** Assertion failure in -[NSLayoutConstraint setPriority:], /SourceCache/Foundation/Foundation-1141.1/Layout.subproj/NSLayoutConstraint.m:174
¿Cuál es mi error aquí?
fuente
required
adefaultLow
y funcionó. El mismo código usado para fallar en iOS 12.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 resultaría en una excepción en tiempo de ejecución.
El orden correcto es:
surveyViewHeightConstraint.priority = 999; surveyViewHeightConstraint.active = YES;
Para Swift versión 4+
constraintName.priority = UILayoutPriority(rawValue: 999)
fuente
Versión rápida:
myContraint.priority = UILayoutPriority(999.0)
fuente
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;
Asimismo, si desea mostrar la vista:
heightConstraintTwo.priority = 250;
fuente
Espero que este escenario ayude a alguien: tenía dos restricciones, que eran opuestas entre sí, quiero decir que no podían satisfacerse al mismo tiempo, en el constructor de interfaces una de ellas tenía una prioridad 1000 y la otra tenía menos de 1000 prioridad. cuando los cambié en el código, tuve este error:
Finalizando la aplicación debido a una excepción no detectada 'NSInternalInconsistencyException', motivo: 'No se admite la mutación de una prioridad de requerida a no en una restricción instalada (o viceversa). Pasó la prioridad 250 y la prioridad existente era 1000 '.
luego los inicialicé en la función viewDidLoad con valores .defaultHigh y .defaultLow y esto solucionó mi problema.
fuente
Según el
NSLayoutConstraints class
interiorUIKit Module
Ejemplo: -
UIButton
restricciones 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]) }
fuente
viewDidLayoutSubviews
. Ese método se puede llamar varias veces, lo que puede bloquear su aplicación si crea restricciones duplicadas allí.Estaba enfrentando el mismo problema. Como algunas de las respuestas mencionadas anteriormente en iOS 13, el cambio de prioridad funcionará bien, sin embargo, en iOS 12 provocará un bloqueo.
Pude solucionar este problema creando IBOutlet NSLayoutConstraint para esa restricción específica en Storyboard conservando su prioridad a 1000, a continuación se muestra el código para corregirlo.
if (Condition) { surveyViewHeightConstraint.constant = 0; surveyViewHeightConstraint.isActive = false; } else if (index == 1) { surveyViewHeightConstraint.constant = 163; surveyViewHeightConstraint.isActive = True; }
¡¡¡Espero que esto ayude!!! Salud
fuente
Ahora puede, simplemente tome la conexión IBOutlet para sus restricciones, luego use este código.
self.webviewHeight.priority = UILayoutPriority(rawValue: 1000)
fuente