2014-11-17 6 views
24

Ich versuche zu verstehen, wie man Auto Layout verwenden kann, um Elemente relativ zu anderen Ansichten prozentual zu positionieren.Verstehen Multiplikator in Auto-Layout, um relative Positionierung zu verwenden

Zum Beispiel habe ich vor kurzem erfahren, dass Sie die Ansicht einer Unterseite angeben sollen 4% höher liegen als Boden seiner Superview ist durch diese Verwendung:

self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 0.96, constant: 0)) 

Dies macht Sinn für mich, weil ein Multiplikator von 1 ausrichten würde direkt am unteren Rand der Ansicht, so dass Sie diesen Betrag um 4 Prozent verringern können, indem Sie den Multiplikator auf 0,96 ändern.

Aber wie können Sie das gleiche in die andere Richtung tun? Sie möchten angeben, dass der obere Rand eines Labels 4% unterhalb des oberen Bereichs der Superansicht beginnen soll. Wenn Sie die gleiche Zeile verwenden, aber die Attribute in ändern, bedeutet das, dass sie 4% höher als die der Superview ist (aber sie wird nicht vom Bildschirm entfernt). Sie können keinen negativen Multiplikator haben, den ich nicht denke, und ich glaube nicht, dass ein Wert größer als 1 irgendetwas tut, wenn Konstante 0 ist. Wie bekommen Sie das?

Ich habe die gleiche Frage für die Implementierung von führenden und nachlaufenden. Trailing ist einfach. Wenn Sie es 10% vom rechten wollen:

self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Trailing, relatedBy: .Equal, toItem: self.view, attribute: .Trailing, multiplier: 0.9, constant: 0)) 

Es macht Sinn, weil Sie sie wählen zurück 0,1 oder 10% statt voll bei 1,0 auszurichten. Aber wie machst du das gleiche für die Führung? Ich dachte, dass Sie möglicherweise den führenden Relativwert der Beschriftung zu dem Nachlauf der Ansicht festlegen können, und legen Sie dann den Multiplikator auf 0,1 fest. In meinen Augen würde das bedeuten, dass das Label ganz rechts beginnen würde, aber dann wieder 90% gewählt werden würde, um die gewünschten 10% von links zu bekommen. Aber das ist nicht der Fall, ich bin mir nicht sicher warum.

Können Sie erklären, wie dies funktioniert, wie Sie den Multiplikator richtig verwenden, um diese relativen Layouts zu erhalten?

Um es einfach zu machen, sagen wir, Sie möchten ein Label erstellen, das oben und unten 10% der Superview-Höhe und 10% der Superview-Breite hat. Auf einem iPhone im Portrait, es geht um mehr Polsterung über und unter dem Etikett zu sein, als es Polsterung nach links und rechts davon ist, wie so (ja es maßstäblich ist gezeichnet):
enter image description here

Aber lassen Sie sich auf dem iPad sagen es wird in einer Ansicht gezeigt, die ein perfektes Quadrat ist. Daher wird die Polsterung überall gleich groß sein:


Die Frage ist, wie definieren Sie solche Einschränkungen als dynamisch im Wert, im Gegensatz zum Festlegen eines festen Werts für eine Konstante. Ich weiß bereits, wie man den Boden und den Trail macht, aber Spitze und Vorsprung haben mich ratlos gemacht. Ich hoffe zu verstehen, wie man den Multiplikator benutzt, um komplexere Layouts zu erstellen, zum Beispiel, dass die Oberkante eines Labels 10% unter der Unterseite eines anderen Labels liegen sollte, anstatt es auf eine feste Konstante zu setzen.

+0

Können Sie zeigen ein Diagramm von dem, was Sie erreichen wollen? – matt

+0

Für diese sehr alte QA .. ist der grundlegende Ansatz, "Abstandhalter" oder "Mess" Ansichten zu verwenden. Markieren Sie sie einfach als versteckt. Sie machen alle Berechnungen für Sie. – Fattie

Antwort

22

Es gibt mehrere Möglichkeiten, dies zu tun.Im einfachsten Fall haben Sie es schon fast geschafft: Wenn Sie möchten, dass die horizontalen Grenzen bei 10% und 90% liegen, müssen Sie beide Constraints in Bezug auf die hintere Kante der Superview angeben - also Subview.Trailing Schlösser Superview.Trailing mit einem Multiplikator von 0.9, wie Sie sagen, aber dann sperren Subview.Leading auch mit einem Multiplikator von 0.1 zu Superview.Trailing, nur:

enter image description here

(und in ähnlicher Weise für die oben/unten)

On auf der anderen Seite, die Der Fall, den du am Ende erwähnst, ist ein wenig komplizierter: "Die Angabe des oberen Endes eines Labels sollte 10% unter dem unteren Rand eines anderen Labels liegen." Dafür werden Sie wahrscheinlich keine festen Prozentsätze wie im vorherigen Fall verwenden können. Stattdessen können Sie eine unsichtbare Spacer-Ansicht zwischen ihnen erstellen: Fügen Sie eine Integritätsbedingung mit Spacer.Height = 0.1 * Superview.Height hinzu und hängen Sie sie dann zwischen den beiden Labels an. (Sie können auch den vorherigen Fall mit diesen Spacer-Ansichten behandeln, aber für diesen Fall ist es nicht wirklich notwendig.)

+2

Ihre Antwort verdeutlicht meiner Meinung nach eines der wichtigsten Auto-Layout-Probleme. Ich danke dir sehr! – Darko

7

Meiner Meinung nach "Sie können keinen negativen Multiplikator haben, denke ich nicht, und ich glaube nicht, dass ein Wert größer als 1 irgendetwas tut, wenn die Konstante 0 ist.

Die Regel unter der Haube ist nur eine lineare Gleichung:

FirstItem.Attribute1 = (SecondItem.Attribute2 * Multiplier) + Constant 

Alle in Punkten gemessen. Wie Sie sehen, ist der Multiplikator (eine Eigenschaft von NSLayoutConstraint) nicht der Multiplikator der Konstante. Befolgen Sie die Gleichung, was Sie nicht verstehen, wird klar sein.

In Bezug auf Ihre speziellen Beispiel präsentiert @Archaeopterasa eine große Lösung wird eine weitere unten gezeigt:

Basierend auf der Tatsache Sie wissen, wie unten zu tun und Hinter, ich nehme an, Sie diese beiden getan haben. Dann fügen Sie zwei weitere Einschränkungen, wird der Effekt sein, was Sie wollen: set label's width to 80% superview's width set label's height to 80% superview's height

Endlich, wenn Sie mit einem Etikett des oben liegen 10% unter einem anderen Label der Unterseite festlegen möchten, scheint es, dass Sie es nicht ohne Schreibgerät kann eine Codezeile. Sie müssen Code verwenden, um die Konstante des NSLayoutConstraint-Objekts festzulegen, das FirstItem und SecondItem verbindet, nachdem die Höhe der Superview in Runtime bekannt ist.

Zum einen Steuer ziehen Sie von einem Etikett zum anderen und wählen „Vertical Spacing“ (Sie können auch auf andere Weise dies tun)

Zweitens eine Referenzierung Steckdose benötigt wird.

@IBOutlet weak var tenPercentOfSuperview: NSLayoutConstraint! 

dann tut dies in einer entsprechenden Stelle (zum Beispiel in viewDidLoad())

let heightOfSuperview = self.view.bounds.height 
tenPercentOfSuperview.constant = heightOfSuperview * 0.1 

Alles ist jetzt in Ordnung.

Wenn Sie mehr über dieses Thema wissen wollen, ist Apples Dokument empfohlen: https://developer.apple.com/library/ios/recipes/xcode_help-IB_auto_layout/chapters/EditingConstraintAttributesintheAttributesInspector.html

4

Hier wird das zu tun, es

UNGLAUBLICH EINFACH

Weg.

Fügen Sie einfach ‚Helfer‘ oder „Maßnahme‘ Ansichten:

Die ‚Ansichten‘ Berechnung Helfer im Beispiel gelb sind

Die allgemeine Technik ist so einfach und klar - es muss nicht jeder. explantion, können Sie es aus dem Bild bekommen.

es ist eines dieser „Elefant im Raum“ Dinge, die sie in iOS „nicht Sie lehren“. Aber es verwendet wird, ständig in allen Layouts.

(In der Tat sollte Apple eine spezielle UIView-Unterklasse erstellt haben „Maßnahmen“ für genau diesen Zweck - und in der Tat haben viele großen Teams nur, dass mit den offensichtlichen Funktionen)

enter image description here

Hinweis Symbol # 1 auf der rechten Seite des „View zentrieren 1/4. "Hilfsansicht.

Das Hinweissymbol # 3 befindet sich am linken Ende der Hilfsansicht "Ansicht 3/4".

Sie sind fertig, haben Sie einen Chardonnay.

Praktischerweise stellen Sie in den Helferansichten einfach den Multiplikator auf den gewünschten Wert ein. Es ist unglaublich einfach, um dann den in Ihrem Code zu ändern, verwenden IBInspectable, belebte, und so weiter und weiter ...

enter image description here