Mam widok, który ma dynamiczną wysokość i próbuję zmienić ten priorytet wysokości widoku w czasie wykonywania.
Oto moja część kodu;
if (index == 0) {
surveyViewHeightConstraint.constant = 0;
surveyViewHeightConstraint.priority = 1000;
} else if (index == 1) {
surveyViewHeightConstraint.constant = 163;
surveyViewHeightConstraint.priority = 500;
}
Zmieniam indeks za pomocą przycisku. Kiedy uruchamiam ten kod, pojawia się ten błąd:
*** Assertion failure in -[NSLayoutConstraint setPriority:], /SourceCache/Foundation/Foundation-1141.1/Layout.subproj/NSLayoutConstraint.m:174
Jaki jest mój błąd tutaj?
źródło
required
nadefaultLow
i zadziałało. Ten sam kod, który został użyty do awarii na iOS 12.Chcę dodać mały dodatek do odpowiedzi Cyrille'a.
Jeśli tworzysz ograniczenie w kodzie, upewnij się, że ustawiłeś jego priorytet przed uaktywnieniem. Na przykład:
surveyViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; surveyViewHeightConstraint.active = YES; surveyViewHeightConstraint.priority = 999;
Spowodowałoby to wyjątek czasu wykonywania.
Prawidłowa kolejność to:
surveyViewHeightConstraint.priority = 999; surveyViewHeightConstraint.active = YES;
Dla wersji Swift 4+
constraintName.priority = UILayoutPriority(rawValue: 999)
źródło
Wersja Swift:
myContraint.priority = UILayoutPriority(999.0)
źródło
Sposób, w jaki zawsze sobie z tym radziliśmy, polega na tym, że nie zmieniamy stałej ograniczenia, tylko priorytet. Na przykład w twojej sytuacji obowiązują dwa ograniczenia wysokości.
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)
jeśli chcesz ukryć widok, musisz:
heightConstraintTwo.priority = 999;
podobnie, jeśli chcesz pokazać widok:
heightConstraintTwo.priority = 250;
źródło
Mam nadzieję, że ten scenariusz komuś pomoże: miałem dwa ograniczenia, że były przeciwne do siebie, to znaczy nie mogły być spełnione w tym samym czasie, w kreatorze interfejsów jeden z nich miał priorytet 1000, a drugi mniej niż 1000. kiedy zmieniałem je w kodzie, miałem ten błąd:
Zamykanie aplikacji z powodu nieprzechwyconego wyjątku „NSInternalInconsistencyException”, powód: „Mutowanie priorytetu z wymaganego na nie w zainstalowanym ograniczeniu (lub odwrotnie) nie jest obsługiwane. Przekroczyłeś priorytet 250, a istniejący priorytet to 1000. ”
następnie po prostu zainicjowałem je w funkcji viewDidLoad z wartościami .defaultHigh i .defaultLow i to rozwiązało mój problem.
źródło
Według
NSLayoutConstraints class
środkaUIKit Module
Przykład: -
UIButton
ograniczenia o różnych priorytetach -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]) }
źródło
viewDidLayoutSubviews
. Tę metodę można wywołać kilka razy, co może spowodować awarię aplikacji, jeśli utworzysz tam zduplikowane ograniczenia.Miałem ten sam problem. Ponieważ niektóre odpowiedzi wymienione powyżej w iOS 13 zmiana priorytetu będą działać dobrze, jednak w iOS 12 doprowadzi to do awarii.
Udało mi się rozwiązać ten problem, tworząc IBOutlet NSLayoutConstraint do tego konkretnego ograniczenia w Storyboard, zachowując jego priorytet na 1000, poniżej znajduje się kod poprawki.
if (Condition) { surveyViewHeightConstraint.constant = 0; surveyViewHeightConstraint.isActive = false; } else if (index == 1) { surveyViewHeightConstraint.constant = 163; surveyViewHeightConstraint.isActive = True; }
Mam nadzieję że to pomoże!!! Twoje zdrowie
źródło
Teraz możesz, po prostu skorzystaj z połączenia IBOutlet dla swoich ograniczeń, a następnie użyj tego kodu.
self.webviewHeight.priority = UILayoutPriority(rawValue: 1000)
źródło