SwiftUI-Textausrichtung


90

Unter den vielen Eigenschaften der TextAnsicht konnte ich keine Informationen zur Textausrichtung finden. Ich habe in einer Demo gesehen, dass RTL automatisch verarbeitet wird, und wenn Inhalte mithilfe von Ansichten platziert werden body, werden sie immer automatisch zentriert.

Gibt es ein Konzept, das mir beim Layoutsystem fehlt, SwiftUIund wenn nicht, wie kann ich die Eigenschaften für die Textausrichtung auf festlegen Text?

Antworten:



85

Ab SwiftUI Beta 3 können Sie eine Textansicht mit dem Frame-Modifikator zentrieren:

Text("Centered")
    .frame(maxWidth: .infinity, alignment: .center)

39

Ich habe versucht, dies selbst zu verstehen, da andere Antworten hier erwähnen Text.multilineTextAlignment(_:)/ VStack(alignment:)/, frame(width:alignment:)aber jede Lösung löst ein bestimmtes Problem. Letztendlich hängt es von der UI-Anforderung und einer Kombination davon ab.


VStack(alignment:)

Das alignmenthier ist für die inneren Ansichten in Bezug aufeinander.
Das Spezifizieren .leadingwürde also alle inneren Ansichten so verknüpfen, dass ihre Führung miteinander ausgerichtet ist.

VStack(alignment: .leading, spacing: 6) {
  Text("Lorem ipsum dolor")
        .background(Color.gray.opacity(0.2))
  Text("sit amet")
        .background(Color.gray.opacity(0.2))
}
.background(Color.gray.opacity(0.1))

Bild


.frame

In frame(width:alignment:)oder frame(maxWidth:alignment:)steht das alignmentfür den Inhalt innerhalb der angegebenen Breite.

VStack(alignment: .leading, spacing: 6) {
  Text("Lorem ipsum dolor")
      .background(Color.gray.opacity(0.2))
  Text("sit amet")
      .background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))

Die inneren Ansichten sind jeweils zueinander ausgerichtet, aber die Ansichten selbst sind nacheinander ausgerichtet VStack.

Bild


.multilineTextAlignment

Dies gibt die Ausrichtung des Textes im Inneren an und kann am besten gesehen werden, wenn mehrere Zeilen vorhanden sind. Andernfalls frame(width:alignment)wird die Breite automatisch angepasst und von den Standardeinstellungen beeinflusst alignment.

VStack(alignment: .trailing, spacing: 6) {
  Text("0. automatic frame\n+ view at parent's specified alignment\n+ multilineTA not set by default at leading")
    .background(Color.gray.opacity(0.2))
  Text("1. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to center")
  .multilineTextAlignment(.center)
  .background(Color.gray.opacity(0.2))
  Text("2. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to trailing")
  .multilineTextAlignment(.trailing)
  .background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))

Bild


Tests mit Kombinationen:

VStack(alignment: .trailing, spacing: 6) {
  Text("1. automatic frame, at parent's alignment")
  .background(Color.gray.opacity(0.2))
  Text("2. given full width & leading alignment\n+ multilineTA at default leading")
  .frame(maxWidth: .infinity, alignment: .leading)
  .background(Color.gray.opacity(0.2))
  Text("3. given full width & center alignment\n+ multilineTA at default leading")
  .frame(maxWidth: .infinity, alignment: .center)
  .background(Color.gray.opacity(0.2))
  Text("4. given full width & center alignment\n+ multilineTA set to center")
  .multilineTextAlignment(.center)
  .frame(maxWidth: .infinity, alignment: .center)
  .background(Color.gray.opacity(0.2))
  Text("5. given full width & center alignment\n+ multilineTA set to trailing")
  .multilineTextAlignment(.trailing)
  .frame(maxWidth: .infinity, alignment: .center)
  .background(Color.gray.opacity(0.2))
  Text("6. given full width but no alignment\n+ multilineTA at default leading\n+ leading is based on content, looks odd sometimes as seen here")
  .frame(maxWidth: .infinity)
  .background(Color.gray.opacity(0.2))
}
.frame(width: 380)
.background(Color.gray.opacity(0.1))

Bild


1
Das ist eine sehr überzeugende Antwort. Vielen Dank. Ich werde in Betracht ziehen, dies auch als akzeptierte Antwort zu betrachten.
Inokey

1
@inokey freut sich, meine Beobachtungen zu teilen :) Ich fand später einen interessanten Artikel, der sich eingehender mit der Ausrichtung von Ansichten im Allgemeinen befasste
staticVoidMan

Super Zeug Mann. SwiftUI hat sich wirklich weiterentwickelt, seit ich diese Frage ursprünglich gestellt habe.
Inokey

17

Ich bin tatsächlich auf das Problem gestoßen, bei dem ich Text in einer einzelnen Zeile ausrichten musste. Was ich gefunden habe, um zu arbeiten, ist Folgendes:

Text("some text")
    .frame(alignment: .leading)

Wenn Sie dies mit dem Parameter für die Rahmenbreite kombinieren, erhalten Sie eine nette Textblockformatierung für Beschriftungen und dergleichen.


14

ich vermute SwiftUI wir sollten für solche Dinge Wrapper wie Stapel verwenden.

Anstatt so etwas zu schreiben Text("Hello World").aligned(.leading), wird Folgendes empfohlen:

VStack(alignment: .leading) {
    Text("Hello World")
}

1
Ich kann also nicht einfach ein stapelunabhängiges Etikett ablegen?
Inokey

@inokey Ich habe zumindest keinen Modifikator dafür gefunden.
Fredpi

Ich habe es auch nicht getan. Mir scheint, ich vermisse eine Art Basiskonzept von SUI. Ich kann nicht einmal wie die "Ansicht" zwischen zwei Dingen fallen lassen und ihr eine Farbe geben, als hätten sie dort kein einfaches a-la-uiview-Objekt.
Inokey

Der Frame-Modifikator hat einen Ausrichtungsparameter
EmilioPelaez

Scheint albern zu müssen (obwohl es funktioniert). Wo haben Sie gehört, dass dies gefördert wurde?
MobileMon

6

Wenn Sie die Breite des Textes konstant halten möchten, wird die ".multilineTextAlignment (.leading)" erst wirksam, wenn nur eine Textzeile vorhanden ist.

Dies ist die Lösung, die für mich funktioniert hat:

struct LeftAligned: ViewModifier {
    func body(content: Content) -> some View {
        HStack {
            content
            Spacer()
        }
    }
}


extension View {
    func leftAligned() -> some View {
        return self.modifier(LeftAligned())
    }
}

Verwendung:

Text("Hello").leftAligned().frame(width: 300)

5

Wir müssen den Text ausrichten und nicht den Stapel, in dem er sich befindet. multilineTextAlignment(.center)Wenn ich also die Zeilengrenzen aufrufe und einstelle, kann ich sehen, dass die Texte zur Mitte ausgerichtet sind. Ich weiß nicht, warum ich die Zeilengrenzen festlegen muss. Ich dachte, es würde sich erweitern, wenn Sie einen großen Text haben.

Text("blahblah")
        .font(.headline)
        .multilineTextAlignment(.center)
        .lineLimit(50)

4

Sie können die Ausrichtung für Vertical stackView als führend festlegen. Wie unten

 VStack(alignment: .leading) {
            Text("Turtle Rock")
                .font(.title)
            Text("Joshua Tree National Park")
                .font(.subheadline)
        }

Geben Sie hier die Bildbeschreibung ein


0

Ich möchte die Spacer () - Ansicht zum Ausrichten von Textblöcken verwenden. Dieses Beispiel zeigt Text auf der hinteren Seite:

                HStack{
                    Spacer()
                    Text("Wishlist")
                }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.