Verschachtelte UIStackViews Gebrochen Einschränkungen
Ich habe eine komplexe view-Hierarchie, built in Interface Builder, mit verschachtelten UIStackViews. Ich bekomme "unerfüllbar Einschränkungen" bemerkt jedes mal, wenn ich etwas zu verbergen von meiner inneren stackviews. Ich habe verfolgt, es unten zu diesem:
(
"<NSLayoutConstraint:0x1396632d0 'UISV-canvas-connection' UIStackView:0x1392c5020.top == UILabel:0x13960cd30'Also available on iBooks'.top>",
"<NSLayoutConstraint:0x139663470 'UISV-canvas-connection' V:[UIButton:0x139554f80]-(0)-| (Names: '|':UIStackView:0x1392c5020 )>",
"<NSLayoutConstraint:0x139552350 'UISV-hiding' V:[UIStackView:0x1392c5020(0)]>",
"<NSLayoutConstraint:0x139663890 'UISV-spacing' V:[UILabel:0x13960cd30'Also available on iBooks']-(8)-[UIButton:0x139554f80]>"
)
Insbesondere die UISV-spacing
Einschränkung: beim ausblenden eines UIStackView seine hohe Einschränkung bekommt eine 0 konstant, aber das scheint zu kollidieren mit dem inneren stackview Abstand-constraint: es erfordert 8 Punkte zwischen meinem Label und Button, die unvereinbar ist mit dem verstecken von constraint-und so die Einschränkungen Absturz.
Gibt es eine Möglichkeit, um dieses? Ich habe versucht rekursiv ausblenden alle inneren StackViews der versteckten Stapel-Ansicht, sondern, dass die Ergebnisse in seltsamen Animationen, wo der Inhalt schwimmt nach oben aus dem Bildschirm, und verursacht starke FPS-drops zu Booten, während immer noch nicht das problem zu lösen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Idealerweise könnten wir nur die Priorität des
UISV-spacing
Einschränkung auf einen niedrigeren Wert, aber es scheint nicht zu irgendeiner Weise zu tun. 🙂Bin ich mit Erfolg die Einstellung der
spacing
Eigenschaft der geschachtelten stack-Ansichten 0 vor versteckt, und die Wiederherstellung auf den richtigen Wert nach macht es wieder sichtbar.Ich denke, dies zu tun rekursiv auf geschachtelten stack-Ansichten funktionieren würde. Man könnte speichern, wird der ursprüngliche Wert des
spacing
Eigenschaft in einem Wörterbuch und Sie später wiederherstellen.Mein Projekt hat nur eine Ebene der Verschachtelung, also ich bin nicht sicher, ob das Ergebnis in FPS Probleme. Solange Sie nicht animieren, die Veränderungen in der Abstand, ich glaube nicht, es würde zu viel von einem hit.
Dies ist ein bekanntes problem mit dem ausblenden von geschachtelten stack-Ansichten.
Gibt es im wesentlichen 3 Lösungen für dieses problem:
innerStackView.removeFromSuperview()
, aber dann müssen Sie sich daran zu erinnern, wo zum einfügen der übersicht.Die 3. option ist die beste meiner Meinung nach. Für weitere Informationen über dieses problem, warum es passiert, die verschiedenen Lösungen, und wie zu implementierende Lösung 3, siehe meine Antwort auf eine ähnliche Frage.
Traf ich ein ähnliches problem mit UISV-Versteck. Für mich war die Lösung zu reduzieren, die Prioritäten meiner eigenen Einschränkungen Erforderlich (1000), etwas weniger als das. Wenn UISV-Versteck Einschränkungen Hinzugefügt werden, Sie haben Vorrang und die Einschränkungen nicht mehr aufeinandertreffen.
So, Sie haben diese:
Und das problem ist, wenn Sie zuerst kollabieren die inneren Stapel, erhalten Sie auto-layout-Fehler:
Dem problem, wie Sie angemerkt haben, ist, dass die äußeren stack-Ansicht gilt Höhe = 0 Einschränkung der innere stack-Ansicht. Diese Konflikte mit dem 8-Punkte-Polsterung-Einschränkung angewendet, indem die inneren Stapel Ansicht zwischen Ihren eigenen Untersichten. Beide Einschränkungen können nicht zufrieden sein gleichzeitig.
Den äußeren Stapel-Ansicht, wird diese Höhe = 0 Einschränkung, ich glaube, da sieht es besser aus, als animiert als nur die Vermietung der Blick nach innen versteckt werden, ohne zu schrumpfen ersten.
Gibt es eine einfache Lösung für dieses Problem: wickeln Sie das innere stack-Ansicht in einer Ebene
UIView
ausblenden und die wrapper. Ich werde unter Beweis stellen.Hier ist die Szene, Gliederung für die fehlerhafte version oben:
Um das problem zu beheben, wählen Sie die innere übersicht. Aus der Menüleiste, wählen Sie " Editor > Einbetten In > Ansicht:
Interface Builder erstellt eine Breite Einschränkung für die wrapper-Ansicht, wenn ich dies getan habe, so zu löschen, dass die Breite Einschränkung:
Als Nächstes erstellen Sie constraints zwischen allen vier Kanten der Hülle und die innere übersicht:
Zu diesem Zeitpunkt, das layout ist tatsächlich korrekt zur Laufzeit, sondern der Interface Builder zieht es falsch. Sie können das Problem beheben, indem Sie die Einstellung der vertikalen umarmt Prioritäten der innen-stack-Kinder höher. Ich setze Sie um 800:
Haben wir nicht wirklich behoben, die unerfüllbar beschränken problem an dieser Stelle. Dazu finden Sie unten die Einschränkung, dass Sie gerade erstellt haben, und setzen Sie seine Priorität auf weniger als erforderlich. Ändern wir es um 800:
Schließlich, Sie war vermutlich eine Steckdose in Ihrer view-controller angeschlossen, um die innere stack anzeigen, weil Sie verändert wurden seine
hidden
Eigenschaft. Ändern, dass die Steckdose, um die Verbindung zu den wrapper-Ansicht statt der inneren stack-Ansicht. Wenn Ihre Steckdose Typ istUIStackView
müssen Sie ändern, um es zuUIView
. Mir war schon der TypUIView
, also bin ich einfach wieder in das storyboard:Nun, beim Umschalten der wrapper-Ansicht
hidden
Eigenschaft, die stack-Ansicht wird angezeigt, um zu kollabieren, ohne unerfüllbar Einschränkung Warnungen. Es sieht praktisch identisch aus, so dass ich nicht die Mühe Entsendung ein weiteres GIF von der app ausgeführt.Finden Sie mein test-Projekt in diesem github-repository.
Ein weiterer Ansatz
Versuchen zu vermeiden, verschachtelte UIStackViews. Ich Liebe Sie, und bauen fast alles mit. Aber als ich sah, dass Sie heimlich fügen Sie Einschränkungen ich versuche nur, Sie auf dem höchsten Niveau und nicht verschachtelte wo es möglich ist. Auf diese Weise kann ich angeben, der 2. höchste Priorität
.defaultHigh
den Abständen Einschränkung der behebt meine Warnungen.Diese Priorität ist gerade genug, um zu verhindern, dass die meisten layout-Probleme.
Natürlich müssen Sie einige weitere Einschränkungen, aber auf diese Weise haben Sie die volle Kontrolle über Sie und machen Ihre Ansicht deutlich.
Hier ist die Umsetzung Sinnvoll ist Vorschlag #3 geschrieben, die als Swift 3-Klasse mit SnapKit Einschränkungen. Ich habe auch versucht das überschreiben der Eigenschaften, aber nie bekam er arbeitet ohne Warnungen, also ich ' ll stick mit Verpackung UIStackView: