Ich sehe verschiedene Beispiele, in denen Einschränkungen festgelegt werden. Einige setzen sie in viewDidLoad
/ loadView
(nachdem die Unteransicht hinzugefügt wurde). Andere setzen sie in der Methode updateViewConstraints
, die von aufgerufen wird viewDidAppear
.
Wenn ich versuche, Einschränkungen updateViewContraints
festzulegen, kann das Layout nervös werden, z. B. eine leichte Verzögerung, bevor die Ansicht angezeigt wird. Wenn ich diese Methode verwende, sollte ich zuerst vorhandene Einschränkungen beseitigen, z [self.view [removeConstraints:self.view.constraints]
.
ios
cocoa-touch
autolayout
Heisenberg
quelle
quelle
updateViewConstraints
: Sie können diese Methode in einer Unterklasse überschreiben, um der Ansicht oder ihren Unteransichten Einschränkungen hinzuzufügen. (aus den Apple-Dokumenten )Antworten:
Ich habe meine Einschränkungen in
viewDidLoad
/ eingerichtetloadView
(ich ziele auf iOS> = 6 ab).updateViewConstraints
ist nützlich, um Werte von Einschränkungen zu ändern. Wenn beispielsweise eine Einschränkung von der Ausrichtung des Bildschirms abhängt (ich weiß, es ist eine schlechte Vorgehensweise), können Sie dieseconstant
in dieser Methode ändern .Das Hinzufügen von Einschränkungen in
viewDidLoad
wird während der Sitzung "Einführung in das automatische Layout für iOS und OS X" (WWDC 2012) ab 39:22 angezeigt. Ich denke, es ist eines der Dinge, die während der Vorlesungen gesagt werden, aber nicht in der Dokumentation landen.UPDATE: Ich habe die Erwähnung des Einrichtens von Einschränkungen in der Ressourcenverwaltung in View Controllern bemerkt :
UPDATE 2 : Während der WWDC 2015 Apple eine neue Erklärung gab von
updateConstraints
undupdateViewConstraints
empfohlene Verwendung:quelle
@"|-[button1]-[button2]-|"
im ViewController festlegen, oder? Oder gibt es einen anderen Weg?updateViewConstraints
?Ich empfehle, ein BOOL zu erstellen und in
-updateConstraints
UIView (oder-updateViewConstraints
für UIViewController) festzulegen.-[UIView updateConstraints]
: (Apple Docs)Beides
-updateConstraints
und-updateViewConstraints
kann während der Lebensdauer einer Ansicht mehrmals aufgerufen werden. (setNeedsUpdateConstraints
Wenn Sie eine Ansicht aufrufen, wird dies beispielsweise ausgelöst.) Daher müssen Sie sicherstellen, dass keine doppelten Einschränkungen erstellt und aktiviert werden - entweder mithilfe eines BOOL, um bestimmte Einschränkungen nur einmal einzurichten, oder indem Sie sicherstellen zum Deaktivieren / Entfernen vorhandener Einschränkungen, bevor neue Einschränkungen erstellt und aktiviert werden.Zum Beispiel:
- (void)updateConstraints { // for view controllers, use -updateViewConstraints if (!_hasLoadedConstraints) { _hasLoadedConstraints = YES; // create your constraints } [super updateConstraints]; }
Ein Hoch auf @fresidue in den Kommentaren, um darauf hinzuweisen, dass Apples Dokumente den Anruf
super
als letzten Schritt empfehlen . Wenn Sie aufrufen,super
bevor Sie Änderungen an einigen Einschränkungen vornehmen, kann es zu einer Laufzeitausnahme (Absturz) kommen.quelle
-updateConstraints
oder so - es würde immer noch aufgerufen und Sie rufen immer noch an[super updateConstraints]
.super
am Ende Ihrer Implementierung von-updateConstraints
oder auf-updateViewConstraints
. Weitere Informationen finden Sie in diesem Kommentar .Dies sollte in ViewDidLoad gemäß dem WWDC-Video von Apple und der Dokumentation erfolgen.
Keine Ahnung, warum Leute updateConstraints empfehlen. Wenn Sie dies in updateConstraints tun, treten Probleme mit NSAutoresizingMaskLayoutConstraint mit automatischer Größenänderung auf, da Ihre Ansichten die automatischen Masken bereits berücksichtigt haben. Sie müssten sie in updateConstraints entfernen, damit sie funktionieren.
UpdateConstraints sollten genau dafür gedacht sein, wenn Sie sie "aktualisieren" müssen, Änderungen usw. gegenüber Ihrer Ersteinrichtung vornehmen müssen.
quelle
Tun Sie es in der Ansicht hat Layout-Unteransichten Methode
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() }
quelle
Ich habe diese Lösung, um Einschränkungen zu ändern, bevor diejenigen, die sich im Storyboard befinden, geladen werden. Diese Lösung entfernt alle Verzögerungen, nachdem die Ansicht geladen wurde.
-(void)updateViewConstraints{ dispatch_async(dispatch_get_main_queue(), ^{ //Modify here your Constraint -> Activate the new constraint and deactivate the old one self.yourContraintA.active = true; self.yourContraintB.active= false; //ecc.. }); [super updateViewConstraints]; // This must be the last thing that you do here -> if! ->Crash! }
quelle
Sie können sie auch in viewWillLayoutSubviews festlegen :
override func viewWillLayoutSubviews() { if(!wasViewLoaded){ wasViewLoaded = true //update constraint //also maybe add a subview } }
quelle
Das hat bei mir funktioniert:
Swift 4.2
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Modify your constraints in here ... }
Obwohl ich ehrlich gesagt nicht sicher bin, ob es sich lohnt. Das Laden scheint etwas langsamer zu sein als in viewDidLoad (). Ich wollte sie nur aus letzterem herausholen, weil es massiv wird.
quelle
Das folgende Beispiel soll eine Ansicht an eine andere Klasse übergeben. Erstelle meine Ansicht aus dem Storyboard
Swift 5.0
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) DispatchQueue.main.async { self.abcInstance = ABC(frame: self.myView.frame) } }
quelle