Alignement de texte SwiftUI


90

Parmi les nombreuses propriétés de la Textvue, je n'ai pas trouvé de propriétés liées à l'alignement du texte. J'ai vu dans une démo qu'il gère automatiquement RTL, et lors du placement de choses à l'aide de View body, il le centre toujours automatiquement.

Y a-t-il un concept qui me manque à propos du système de mise en page SwiftUIet sinon, comment puis-je définir les propriétés d'alignement du texte sur le Text?

Réponses:



85

À partir de SwiftUI beta 3, vous pouvez centrer une vue de texte avec le modificateur de cadre:

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

39

J'essayais de comprendre cela moi-même comme d'autres réponses mentionnent ici Text.multilineTextAlignment(_:)/ VStack(alignment:)/ frame(width:alignment:)mais chaque solution résout un problème spécifique. Finalement, cela dépend des exigences de l'interface utilisateur et d'une combinaison de celles-ci.


VStack(alignment:)

Le alignmentvoici pour les vues intérieures les unes par rapport aux autres.
Ainsi, la spécification .leadingassocierait toutes les vues intérieures pour que leur direction soit alignée les unes sur les autres.

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))

image


.frame

Dans frame(width:alignment:)ou frame(maxWidth:alignment:), le alignmentest pour le contenu dans la largeur donnée.

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))

Les vues intérieures sont alignées en tête respectivement les unes par rapport aux autres mais les vues elles-mêmes sont alignées en arrière respectivement par rapport au VStack.

image


.multilineTextAlignment

Cela spécifie l'alignement du texte à l'intérieur et peut être mieux vu lorsqu'il y a plusieurs lignes sinon sans définition frame(width:alignment), la largeur est automatiquement ajustée et est affectée par les valeurs par défaut 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))

image


Tests avec combinaisons:

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))

image


1
C'est une réponse très convaincante. Merci. J'envisagerai également d'en faire une réponse acceptée.
inokey

@inokey heureux de partager mes observations :) J'ai trouvé plus tard un article intéressant qui approfondissait les alignements de vue en général: Guides d'alignement dans SwiftUI
staticVoidMan

homme de trucs génial. SwiftUI a vraiment évolué depuis que j'ai initialement publié cette question.
inokey

17

En fait, j'ai rencontré le problème où je devais aligner le texte sur une seule ligne. Voici ce que j'ai trouvé pour fonctionner:

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

Si vous combinez cela avec le paramètre de largeur de cadre, vous pouvez obtenir une bonne mise en forme de bloc de texte pour les étiquettes et autres.


14

Je suppose SwiftUIque nous voulons que nous utilisions des emballages comme des piles pour de telles choses.

Donc, au lieu d'écrire quelque chose comme Text("Hello World").aligned(.leading), ce qui suit est encouragé:

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

1
Je ne peux donc pas simplement supprimer une étiquette indépendante de la pile?
inokey le

@inokey Je n'ai pas trouvé de modificateur pour cela au moins.
fredpi

Moi non plus. Il me semble que je manque une sorte de concept de base de SUI. Je ne peux même pas laisser tomber comme juste la "vue" entre deux choses, et lui donner une couleur, comme s'ils n'avaient pas d'objet a-la-uiview simple là-dedans.
inokey le

Le modificateur de cadre a un paramètre d'alignement
EmilioPelaez

Cela semble idiot d'avoir à faire (même si cela fonctionne). Où avez-vous entendu dire que cela était encouragé?
MobileMon

6

Si vous souhaitez conserver une largeur constante pour le texte, le ".multilineTextAlignment (.leading)" ne prendra aucun effet tant qu'il n'y aura qu'une seule ligne de texte.

C'est la solution qui a fonctionné pour moi:

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


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

Usage:

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

5

Nous devons aligner le texte et non la pile dans laquelle il se trouve. Ainsi, en appelant multilineTextAlignment(.center)et en définissant les limites de ligne, je peux voir les textes alignés au centre. Je ne sais pas pourquoi je dois définir les limites de ligne, j'ai pensé que cela augmenterait si vous aviez un texte volumineux.

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

4

Vous pouvez définir l'alignement pour Vertical stackView comme leader. Comme ci-dessous

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

entrez la description de l'image ici


0

Je voudrais utiliser la vue Spacer () pour aligner le bloc de texte. Cet exemple montre le texte à la fin:

                HStack{
                    Spacer()
                    Text("Wishlist")
                }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.