Ich habe eine UIView, die über verschiedene Einschränkungen auf dem Bildschirm angezeigt wird. Einige der Einschränkungen gehören der Übersicht, andere anderen Vorfahren (z. B. die Ansichtseigenschaft eines UIViewControllers).
Ich möchte all diese alten Einschränkungen entfernen und sie mithilfe neuer Einschränkungen an einem neuen Ort platzieren.
Wie kann ich dies tun, ohne für jede einzelne Einschränkung ein IBOutlet zu erstellen und mich daran erinnern zu müssen, welcher Ansicht diese Einschränkung gehört?
Um dies zu erläutern, würde der naive Ansatz darin bestehen, eine Reihe von IBOutlets für jede der Einschränkungen zu erstellen und dann Code aufzurufen, wie z.
[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];
Das Problem mit diesem Code ist, dass ich selbst im einfachsten Fall 2 IBOutlets erstellen müsste. Bei komplexen Layouts können leicht 4 oder 8 erforderliche IBOutlets erreicht werden. Außerdem müsste ich sicherstellen, dass mein Aufruf zum Entfernen der Einschränkung in der richtigen Ansicht aufgerufen wird. Stellen Sie sich zum Beispiel vor, das myViewsLeftConstraint
gehört viewA
. Wenn ich versehentlich anrufen [self.view removeConstraint:self.myViewsLeftConstraint]
würde, würde nichts passieren.
Hinweis: Die Methode ConstrainctionsAffectingLayoutForAxis sieht vielversprechend aus, ist jedoch nur für Debugging-Zwecke vorgesehen.
Update: Viele der Antworten , die ich viel erhalte mit self.constraints
, self.superview.constraints
oder irgendeine Variante davon. Diese Lösungen funktionieren nicht, da diese Methoden nur die Einschränkungen zurückgeben, die der Ansicht gehören, nicht diejenigen , die sich auf die Ansicht auswirken .
Berücksichtigen Sie diese Ansichtshierarchie, um das Problem mit diesen Lösungen zu klären:
- Großvater
- Vater
- Mich
- Sohn
- Tochter
- Bruder
- Mich
- Onkel
- Vater
Stellen Sie sich nun vor, wir erstellen die folgenden Einschränkungen und hängen sie immer an den nächsten gemeinsamen Vorfahren an:
- C0: Me: das gleiche Top wie Son (im Besitz von Me)
- C1: Me: width = 100 (im Besitz von Me)
- C2: Ich: gleiche Größe wie Bruder (im Besitz von Vater)
- C3: Ich: das gleiche Top wie Onkel (im Besitz des Großvaters)
- C4: Ich: gleich links wie Großvater (im Besitz von Großvater)
- C5: Bruder: links wie Vater (im Besitz von Vater)
- C6: Onkel: links wie Großvater (im Besitz von Großvater)
- C7: Sohn: links wie Tochter (im Besitz von mir)
Stellen Sie sich nun vor, wir möchten alle betroffenen Einschränkungen entfernen Me
. Jede richtige Lösung sollte entfernt werden [C0,C1,C2,C3,C4]
und sonst nichts.
Wenn ich benutze self.constraints
(wo ich selbst bin), werde ich bekommen [C0,C1,C7]
, da dies die einzigen Einschränkungen sind, die mir gehören. Offensichtlich würde es nicht ausreichen, dies zu entfernen, da es fehlt [C2,C3,C4]
. Darüber hinaus wird es C7
unnötig entfernt.
Wenn ich benutze self.superview.constraints
(wo ich selbst bin), werde ich es bekommen [C2,C5]
, da dies die Zwänge sind, die Vater gehört. Offensichtlich können wir nicht alle diese entfernen, da dies C5
völlig unabhängig ist Me
.
Wenn ich benutze grandfather.constraints
, werde ich bekommen [C3,C4,C6]
. Auch hier können wir nicht alle entfernen, da dies C6
intakt bleiben sollte.
Der Brute-Force-Ansatz besteht darin, alle Vorfahren der Ansicht (einschließlich sich selbst) zu durchlaufen und zu prüfen, ob firstItem
oder ob secondItem
die Ansicht selbst vorhanden ist. Wenn ja, entfernen Sie diese Einschränkung. Dies führt zu einer korrekten Lösung, der Rückgabe [C0,C1,C2,C3,C4]
und nur diesen Einschränkungen.
Ich hoffe jedoch, dass es eine elegantere Lösung gibt, als die gesamte Liste der Vorfahren durchlaufen zu müssen.