Eu tenho uma visão que tem altura dinâmica e estou tentando mudar essa prioridade de altura da visão em tempo de execução.
Aqui está minha parte do código;
if (index == 0) {
surveyViewHeightConstraint.constant = 0;
surveyViewHeightConstraint.priority = 1000;
} else if (index == 1) {
surveyViewHeightConstraint.constant = 163;
surveyViewHeightConstraint.priority = 500;
}
Estou mudando o índice com uma ação de botão. Quando executo este código, recebo este erro:
*** Assertion failure in -[NSLayoutConstraint setPriority:], /SourceCache/Foundation/Foundation-1141.1/Layout.subproj/NSLayoutConstraint.m:174
Qual é o meu erro aqui?
fonte
required
paradefaultLow
e funcionou. O mesmo código costumava travar no iOS 12.Quero fazer um pequeno acréscimo à resposta de Cyrille.
Se você estiver criando uma restrição no código, certifique-se de definir sua prioridade antes de torná-la ativa. Por exemplo:
surveyViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; surveyViewHeightConstraint.active = YES; surveyViewHeightConstraint.priority = 999;
Isso resultaria em exceção de tempo de execução.
A ordem correta é:
surveyViewHeightConstraint.priority = 999; surveyViewHeightConstraint.active = YES;
Para Swift versão 4+
constraintName.priority = UILayoutPriority(rawValue: 999)
fonte
Versão Swift:
myContraint.priority = UILayoutPriority(999.0)
fonte
A maneira como sempre tratamos disso é não alterando a constante de restrição, apenas a prioridade. Por exemplo, em sua situação, há duas restrições 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)
se quiser ocultar a visualização, você:
heightConstraintTwo.priority = 999;
da mesma forma, se você quiser mostrar a vista:
heightConstraintTwo.priority = 250;
fonte
Espero que este cenário ajude alguém: Eu tinha duas restrições, que eram opostas, quer dizer, não podiam ficar satisfeitas ao mesmo tempo, no construtor de interface um deles tinha 1000 prioridade e outro tinha menos de 1000 prioridade. quando os alterei no código, tive este erro:
Encerrando o aplicativo devido à exceção não detectada 'NSInternalInconsistencyException', motivo: 'A mutação de uma prioridade de necessária para não em uma restrição instalada (ou vice-versa) não é suportada. Você passou a prioridade 250 e a prioridade existente era 1000. '
então, eu apenas os inicializei na função viewDidLoad com os valores .defaultHigh e .defaultLow e isso corrigiu meu problema.
fonte
De acordo com
NSLayoutConstraints class
dentroUIKit Module
Exemplo: -
UIButton
restrições com várias 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]) }
fonte
viewDidLayoutSubviews
. Esse método pode ser chamado várias vezes, o que pode travar seu aplicativo se você criar restrições duplicadas lá.Eu estava enfrentando o mesmo problema. Como algumas das respostas mencionadas acima no iOS 13, alterar a prioridade funcionará bem, mas no iOS 12 isso levará ao travamento.
Consegui corrigir esse problema criando IBOutlet NSLayoutConstraint para essa restrição específica no Storyboard mantendo sua prioridade em 1000, abaixo está o código para correção.
if (Condition) { surveyViewHeightConstraint.constant = 0; surveyViewHeightConstraint.isActive = false; } else if (index == 1) { surveyViewHeightConstraint.constant = 163; surveyViewHeightConstraint.isActive = True; }
Espero que isto ajude!!! Felicidades
fonte
Agora você pode, basta usar a conexão IBOutlet para suas restrições e usar este código.
self.webviewHeight.priority = UILayoutPriority(rawValue: 1000)
fonte