it-swarm.com.de

Automatisches Layout (Einschränkungen) Zentrieren Sie die Ansichten von Seite 2 in einer übergeordneten Ansicht

Ich versuche herauszufinden, wie dies mit dem automatischen Layout (iOS6) und Einschränkungen möglich ist.

Grundsätzlich habe ich meine große Ansicht unten in zwei Abschnitte unterteilt. Innerhalb dieser Abschnitte (derzeit Unteransichten) habe ich eine Bildansicht und eine Beschriftung. Ich möchte diese auf beiden Seiten mit einem Text mit variabler Länge zentrieren.

Mein Kopf ist meistens mit dem automatischen Layout umwickelt, aber ich bin nicht sicher, wie ich das am besten erreichen kann. Ich neige dazu zu denken, dass es in IB nicht möglich ist, aber im Code ist.

Ich werde weiter versuchen, das herauszufinden, aber in der Zwischenzeit hier ist das Beispiel, das ich zu schaffen versuche.

enter image description here

65
Bob Spryn

Ist es das, was Sie suchen?

short labellong label

Ich habe es getan, indem ich eine Ansicht (mit dem Namen viewCenteredInLeftSection) in Ihre leftSection eingefügt habe, und dann das Uhrenbild und die Beschriftung als Unteransichten mit diesen Einschränkungen hinzugefügt habe:

  • Stellen Sie CenterX und CenterY von viewCenteredInLeftSection gleich (leftSection) des Superviews.
  • Verändere die Ober-, Unter- und Vorderkante von clockImage mit der (viewCenteredInLeftSection) des Superview.
  • Verändere die Hinterkante von label gleich der (viewCenteredInLeftSection) des Superview.
  • Machen Sie die Hinterkante von clockImage um den Standardabstand von der Vorderkante von label.

viewCenteredInLeftSection

Ich habe Probleme beim Ändern der Größe von iOS-UIViews im Interface Builder. Deshalb habe ich mein Beispiel für OS X erstellt und konnte dies vollständig im Interface Builder tun. Wenn Sie Schwierigkeiten haben, die oben genannten Einschränkungen im Interface Builder zu treffen, lassen Sie es mich wissen, und ich gebe Code ein, der sie erstellt.

2014-08-26 Bearbeiten

Luda , hier sind die Pin- und Align-Menüs von Xcode 5, die auch in der Xcode-Menüleiste verfügbar sind:

Align menuPin menu

Nachfolgend sehen Sie mein Beispiel im Interface Builder. Die blaue Ansicht ist die "übergeordnete Ansicht" aus der ursprünglichen Frage, der angegebenen Ansicht, in der Bild und Beschriftung zentriert werden sollen.

Ich habe die grüne Ansicht (die ich viewCenteredInLeftSection genannt habe) als Unteransicht von "übergeordneter Ansicht" hinzugefügt. Dann habe ich es hervorgehoben und die Ausrichtungsmenüs "Horizontal Center in Container" und "Vertical Center in Container" verwendet, um Einschränkungen zu definieren, um seine Position zu definieren.

Ich habe das Uhrenbild als Unteransicht von viewCenteredInLeftSection hinzugefügt, wobei die Breite und Höhe durch Einschränkungen definiert werden. Ich hob das Uhrenbild und viewCenteredInLeftSection hervor und wendete dann Einschränkungen mit Ausrichten> Führende Kanten, Ausrichten> Oberste Kanten und Ausrichtung> Untere Kanten an.

Ich fügte das Label als Unteransicht von viewCenteredInLeftSection hinzu und positionierte es als Standard-Aqua-Abstand vom Uhrbild. Ich hob die Beschriftung und viewCenteredInLeftSection hervor und wendete dann die Beschränkungen mit Align> Trailing Edges an.

Dies war viel einfacher zu erstellen mit Xcode 5 Interface Builder im Vergleich zu Xcode 4.

Interface Builder

59
John Sauer

Ich habe einen Weg gefunden, ohne eine andere Ansicht hinzuzufügen:

 [aView addConstraint:[NSLayoutConstraint constraintWithItem:viewOnLeft attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationLessThanOrEqual toItem:aView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
 [aView addConstraint:[NSLayoutConstraint constraintWithItem:viewOnRight attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationLessThanOrEqual toItem:aView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];

Sie können auch die Konstanten ändern, um eine Lücke zwischen den Ansichten zu erzeugen.

  • konstante der linken Ansicht: -X
  • konstante für rechte Ansicht: +X

centering subviews

29
Lucien

Ich habe eine Weile gebraucht, aber ich habe eine ziemlich solide Lösung gefunden. Ich fand die gleiche Lösung, die John Sauer zur Verfügung stellte, wollte aber nicht noch eine weitere Ansicht hinzufügen, um diese einzubinden.

Die Antwort erfordert drei Schritte.

1) Die Breite meiner Unteransicht, die die anderen beiden enthält, die ich leftInfoSection nenne, muss durch deren Inhalt bestimmt werden. Dadurch entfällt die Notwendigkeit, linke und rechte Nebenbedingungen für eine Übersicht (oder eine andere Ansicht) zu haben, um deren Breite zu bestimmen. Das ist ein echter Schlüssel für viele dieser Sachen ist, dass Breiten von Kindern definiert werden.

enter image description here

2) Ich musste immer noch eine führende Einschränkung in IB haben, um ein gültiges Layout zu erhalten. (Es musste wissen, wo die leftInfoSection horizontal platziert werden sollte). Verbinden Sie diese Einschränkung mit Ihrem Code, damit Sie ihn entfernen können. Darüber hinaus hatte ich eine nachlaufende Einschränkung GTE der vertikale Teiler + 3.

3) Der letzte Schlüssel ist zu überlegen, mit welchen Informationen Sie arbeiten müssen (im Code, da IB begrenzt ist). Mir wurde klar, dass ich die Mitte des horizontalen Teilers über meinem Abschnitt kannte und dass die Mitte meines leftInfoSection die Mitte dieses horizontalen Balkens minus 1/4 der Breite des horizontalen Balkens sein würde. Hier ist der endgültige Code für die linke und rechte Seite:

// remove the unwanted constraint to the right side of the thumbnail
[self.questionBox removeConstraint:self.leftInfoViewLeadingConstraint];
// calculate the center of the leftInfoView
CGFloat left = self.horizontalDividerImageView.frame.size.width/4 * -1;
// constrain the center of the leftInfoView to the horizontal bar center minus a quarter of it to center things
[self.questionBox addConstraint:[NSLayoutConstraint constraintWithItem:self.leftInfoView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.horizontalDividerImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:left]];

// remove the unwanted constraint to the right side of the questionBox
[self.questionBox removeConstraint:self.rightInfoViewTrailingConstraint];
// calculate the center of the rightInfoView
CGFloat right = left * -1;
// constrain the center of the rightInfoView to the horizontal bar center plus a quarter of it to center things
[self.questionBox addConstraint:[NSLayoutConstraint constraintWithItem:self.rightInfoView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.horizontalDividerImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:right]];

Ergebnis: Final result

IB kann auch sehr ärgerlich sein, wenn es automatisch Einschränkungen auflöst. Wenn ich versuchte, die führenden und nachlaufenden Abhängigkeiten in den Unteransichten als 0 zu definieren, würde die Verbindung zwischen dem einen oder dem anderen unterbrochen und eine Einschränkung im Superview vorgenommen, um die Breite zu definieren. Der Trick bestand darin, diese unerwünschte Einschränkung vorübergehend beizubehalten, aber die Priorität auf 999 zu senken. Dann konnte ich nur Unteransichtseinschränkungen erstellen, um die Breite zu definieren.

16
Bob Spryn

Eine Lösung dafür wird in stanfords Universitätsvorlesungen zu ios 7 in Betracht gezogen. Es funktioniert wunderbar. (Hier sdfssfg ... Ding ist Label1 und Efsdfg .... Ding ist Label2)

enter image description here

14
Vinayak Parmar

Das funktioniert ziemlich gut, erfordert aber 2 Spacer UIView's:

UIView *spacer1 = [[UIView alloc] init];
spacer1.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:spacer1];

UIView *spacer2 = [[UIView alloc] init];
spacer2.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:spacer2];

NSDictionary *views = NSDictionaryOfVariableBindings(spacer1, spacer2, imageView, label);

[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[spacer1(>=0)][imageView]-4-[label][spacer2(==spacer1)]|" options:0 metrics:nil views:views];

for (int i = 0; i < constraintsArray.count; i++) {

    [self.view addConstraint:constraintsArray[i]];
}
11
Christian

Nach iOS 9 ist eine weitere Möglichkeit, dies zu erreichen, die Verwendung von Stack Views

5
alcamla

Vielleicht möchten Sie das verweisen 

Prozentuale Bewertung

Grundsätzlich heißt es zuerst mit dem falschen Rand und dann in der übergeordneten Ansicht zu korrigieren. 

Mit meinem Fall arbeiten 

0
Amitg2k12

Dafür gibt es mehrere Möglichkeiten. Grundsätzlich gilt Folgendes: 1..n-Elemente zentrieren, vorausgesetzt, alle Ihre Elemente haben bestimmte Größen und werden nicht grow.

  1. Platzieren Sie 2 Abstandhalter auf jeder Seite Ihrer Artikel. Verankern Sie die Abstandhalter an den übergeordneten Kanten. Verankern Sie Ihre ersten und letzten Elemente mit den Ankern. Weisen Sie schließlich 1 Abstandhalter zu, um die Breite des anderen Abstandhalters zu erhalten. Sie müssen keine Abstandhaltergröße explizit festlegen, da dies gelöst ist.

    • spacer1 -> left = parent: left width = spacer2: width
    • spacer2 -> right = parent: right
    • yourFirstItem -> left = spacer1: right
    • yourLastItem -> right = spacer2: left
  2. Wenn Abstandhalter nicht Ihr Ding sind und Sie und Sie eine ungerade Anzahl von Elementen haben, zentrieren Sie den mittleren auf die Mitte des übergeordneten Elements. Stellen Sie außerdem sicher, dass das erste und letzte Element nicht an den übergeordneten Kanten verankert sind.

    • yourMiddleItem = centerX = übergeordnet: centerX
    • otherItems-> yourMiddleItem <-otherItems
  3. Wenn Abstandhalter nicht Ihre Sache sind und Sie eine gerade Anzahl von Elementen haben, zentrieren Sie die Kanten der beiden inneren Elemente auf die Mitte des übergeordneten Elements. Stellen Sie außerdem sicher, dass das erste und letzte Element nicht an den übergeordneten Kanten verankert sind.

    • leftMiddleItem -> right = parent: centerX
    • rightMiddleItem -> left = parent: centerX
    • otherItems-> leftMiddleItem rightMiddleItem <-otherItems
  4. Sie können auch einen unsichtbaren Platzhalter in der Mitte zentrieren und darauf verankern. Sie müssen jedoch bei der Einschränkung eine ungerade/gerade Anzahl von Elementen berücksichtigen, daher empfehle ich diesen Ansatz nicht.

0
Steven Spungin