Autolayout - Stellen Sie die Höhe der Ansicht relativ zur halben Höhe der Übersicht ein

136

Ich habe mich in letzter Zeit mit Autolayouts beschäftigt und bin festgefahren bei einem wirklich trivialen Problembeispiel. Ich habe eine Ansicht, dass ich oben auf dem Bildschirm sitzen und die Hälfte der Bildschirmhöhe einnehmen möchte. Einfach vor dem automatischen Layout - einfach anbringen und anweisen, dass es vertikal erweitert werden soll, wenn die Größe der Übersicht geändert wird.

Jetzt kann ich für mein ganzes Leben nicht sehen, wie es geht. Folgendes bekomme ich, wenn ich versuche, dies einzurichten:

Autolayout-Blues

Die Beschränkung des unteren Speicherplatzes ist auf "gleich 284" festgelegt, was für mich absolut und absolut nutzlos ist, wenn ich zum iPhone4-Layout wechsle, da 284 Punkte am unteren Bildschirmrand verbleiben und die Ansicht auf nicht mehr die Hälfte verkleinert wird Größe des Bildschirms. Und es gibt keine Möglichkeit, diese Einschränkung so einzustellen, dass sie einem Bruchteil der Höhe einer anderen Ansicht entspricht.

Nachdem ich eine Weile gekämpft habe, kann ich mir dies nur vorstellen, indem ich eine andere Ansicht unter dieser Ansicht einführe, ihre Höhen gleichmäßig festnehme, sie über und untereinander sitzen lasse und dann die zweite (untere) Ansicht als unsichtbar einstelle .. was ein bisschen hässlich erscheint!

Vermisse ich etwas Offensichtliches?

Mete
quelle
1
Ich denke nicht, dass es hässlich ist, aber ein kluger Trick, um mit IB das zu bekommen, was Sie wollen. Ich habe dies getan, und wenn Sie die richtigen Elementnamen verwenden, können Sie klarstellen, was los ist. Sie können sogar ein drittes Element an einer anderen Position oder in einer anderen Mitte haben, um die Größe basierend auf diesen beiden Unteransichten zu ändern.
Jelle

Antworten:

167

Dies ist jetzt in IB ab [mindestens] Xcode 5.1.1 möglich. Obwohl ich einige Zeit gebraucht habe, um herauszufinden, ist es eigentlich super einfach:

Erstellen Sie zunächst eine grundlegende Einschränkung für die obere Ausrichtung (Sie müssen auch die unteren, linken und rechten Einschränkungen wie gewohnt festlegen). Wählen Sie dann die Einschränkung aus und navigieren Sie zum Attributinspektor :

Demonstration der obigen Schritte

Dann können Sie den Multiplikator einstellen. Wenn Sie möchten, dass 50% der Superansicht angezeigt werden, belassen Sie 1diese Option, da sie in der Mitte des Supers ausgerichtet ist. Dies ist auch eine großartige Möglichkeit, Ansichten zu erstellen, bei denen es sich auch um andere Prozentsätze handelt (z. B. 25% der Superansicht).

Demonstration des zweiten Schrittes oben

Firo
quelle
nett :) Ich denke, dieser Beitrag sollte als akzeptierte Antwort markiert werden :) iOS-Entwickler bevorzugen oft die Interface Builder-Lösung anstelle der
codeähnlichen
@hqt, danke. Ich denke, als die akzeptierte Antwort geschrieben wurde, war diese Methode nicht verfügbar. Manchmal wiederholen die Fragesteller alte Fragen nicht und möchten die akzeptierte Antwort nicht ändern. Aber letztendlich bin ich nur hier, um zu helfen, froh, dass es so war!
Firo
3
Ich bin ein bisschen verwirrt. Ich habe es versucht, aber es zentriert die Ansicht nur auf die Übersicht, es passt die Höhe der Ansicht nicht an.
Dean
@Dean, müssen Sie sicherstellen , dass das First Itemist View.Topnicht View.Center Y. Andernfalls wird es ja nur zentriert. Sie müssen auch sicherstellen, dass andere Einschränkungen richtig eingestellt sind, um die anderen Kanten der Ansicht zu behandeln.
Firo
1
View.Top ist gleich Superview.Center Y Multiplikator 1 gibt Ihnen keine Höhe. Diese Antwort ist unvollständig. Alles, was Sie tun müssen, ist darüber nachzudenken, was Sie sagen, und Sie können sehen, dass es Ihnen eine Linie durch die Mitte gibt! Ich würde diese Antwort bearbeiten, um klar zu machen, über welche anderen Einschränkungen Sie sprechen.
smileBot
184

Storyboard-Lösung, bei der Sie das genaue Verhältnis zwischen beliebigen Ansichten festlegen können:

Legen Sie die Einschränkung für die Höhengleichheit fest

Jetzt:

Bearbeiten Sie den Multiplikator der Einschränkung

PROFITIEREN!!!

Ergebnis

PS Beachten Sie auch, dass diese Methode mit Ansichten auf verschiedenen Verschachtelungsebenen funktioniert und (offensichtlich) für die Breite gilt

PPS Manchmal kann es hilfreich sein, das erste und zweite Element der Einschränkung "umzukehren" oder den umgekehrten Multiplikator festzulegen (z. B. 2 statt 0,5) (diese Methoden sind jedoch nicht hilfreich, wenn Sie nicht verstehen, wie Ansichten miteinander in Beziehung stehen).

Fjodor Volchyok
quelle
1
Schritt 2 scheint für mich nicht zu funktionieren. Ich kann nichts im Bedienfeld auswählen, außer "Einschränkung auf Rand" umzuschalten. Ich versuche, die Breite einer UIImageView in einer UITableViewCell auf 50% der Inhaltsansicht festzulegen.
DrMickeyLauer
2
UPDATE: Offensichtlich erlaubt der Interface Builder nicht, dass die Inhaltsansicht das explizite Ziel von Einschränkungen für das automatische Layout ist. Ich muss eine Dummy-Unteransicht als untergeordnetes Element der Inhaltsansicht einfügen, damit dies funktioniert.
DrMickeyLauer
1
Für mich geht das. Sie müssen die beiden Ansichten in der Liste auswählen, nicht den Builder-Bildschirm. Für Prozentsätze teilen Sie die kleinere Ansicht durch die größere Ansicht, um den Multiplikatorwert zu erhalten. Beispiel: kleinere Ansicht 25, größere Ansicht 135 - 25/135 = 0,185. Stellen Sie dies als Multiplikatorwert ein, um eine Ansicht zu erhalten, die bei x1 und x2 = 25, aber mit größeren 6 und 6 plus usw.
skaliert
1
Dies funktionierte für mich, aber bitte beachten Sie, dass ich auch drei Einschränkungen hinzufügen musste, die die Randbeschränkungen der Unteransicht auf 0 setzen. Danke
raddevus
Dies sollte die akzeptierte Antwort sein. Zuerst versuche ich eine akzeptierte Antwort. Es hat nicht funktioniert, dann scrolle ich nach unten und ich habe diese Antwort gesehen und es hat funktioniert. Vielen Dank!
Mihir Oza
31

Nach etwas mehr Zeit habe ich mir Folgendes ausgedacht.

Ich nehme es als Antwort zur Kenntnis, aber es ist nicht sehr befriedigend, da davon ausgegangen wird, dass Sie dies in Interface Builder nicht tun können, aber die richtige Einschränkung kann anschließend im Code hinzugefügt werden als:

- (void) viewWillAppear:(BOOL)animated
{

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
                                                                 attribute:NSLayoutAttributeHeight 
                                                                 relatedBy:0 
                                                                    toItem:self.view
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:.5 
                                                                  constant:0];
    [self.view addConstraint:constraint];

}

Grundsätzlich wird ein Multiplikator von 0,5 gegen die Höhe von self.view gesetzt, der auf Upperview wirkt. Ich musste die Priorität der unteren vertikalen Speicherplatzbeschränkung in IB auf weniger als 1000 festlegen, um eine Reihe von Laufzeitnachrichten über das Aufheben von Einschränkungen zu vermeiden.

Wenn also jemand in Interface Builder zeigen kann, wie das geht, würde das meine Frage besser beantworten, sonst denke ich, dass dies so gut ist, wie es (vorerst) geht ???

Mete
quelle
3
Ich denke, das ist so gut wie es jetzt geht. Es wäre schön, wenn Apple uns Zugriff auf den Multiplikatorwert in IB geben würde, damit dieser ebenso wie die Konstante eingestellt werden kann.
Rdelmar
3
Für alle, die sich diese Antwort ansehen, können Sie mit Xcode 5.1 jetzt den Multiplikator über den Interface Builder einstellen. Ich kann jetzt Ansichten, die halb so hoch wie ihre Übersicht sind, über IB konfigurieren.
Mark Krenek
9

Etwas einfacher und direkter als die Methode als die Antwort von Fjodor Volchyok. - Halten Sie die Steuertaste gedrückt und klicken Sie auf die Unteransicht. - Halten Sie die Befehlsschaltfläche gedrückt, ziehen Sie den Cursor auf die Übersicht und klicken Sie auf die Übersicht. -Wählen Sie "Seitenverhältnis".

Geben Sie hier die Bildbeschreibung ein

-Dann klicken Sie auf den Größeninspektor. - Doppelklicken Sie dann auf die Einschränkung. Geben Sie hier die Bildbeschreibung ein

- Stellen Sie sicher, dass für beide Elemente "Höhe" ausgewählt ist. Geben Sie hier die Bildbeschreibung ein

- Ändern Sie dann den "Multiplikator" für die Hälfte des Bildschirms oder den gewünschten Bruchteil der Übersicht auf 0,5. Geben Sie hier die Bildbeschreibung ein

user444333222
quelle
Einfacher und schneller Ansatz! Danke Kumpel
Abdullah Saeed
7

Es gibt auch eine andere Möglichkeit im Code, falls Sie 2 Ansichten haben, die beide dieselbe Höhe haben sollten: Stellen Sie einfach die Höhe von Ansicht2 auf die Höhe von Ansicht1 ein (der Trick hier besteht nicht darin, die Höhe von Ansicht1 explizit festzulegen).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];
Brainstray
quelle
Ich wusste nicht, dass Sie andere Ansichten für solche Breiten / Höhen referenzieren können. Dies ist die sauberste Antwort IMO, wenn Sie bereits in der Sprache des visuellen Formats sind.
Loeschg
@ Brainray Beispiel wird auch auf developer.apple.com hier erklärt
alecs.popa
0

Schnelle Version von Metes Antwort:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.



    upperView.translatesAutoresizingMaskIntoConstraints = false


    var constraint = NSLayoutConstraint(item: upperView,
                                        attribute: NSLayoutAttribute.top,
                                        relatedBy: NSLayoutRelation.equal,
                                        toItem: self.view,
                                        attribute: NSLayoutAttribute.top,
                                        multiplier: 1,
                                        constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.height,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.height,
                                    multiplier: 0.5,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.leading,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.leading,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.trailing,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.trailing,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


}
user444333222
quelle