Alinhamento de texto SwiftUI

90

Entre as muitas propriedades da Textvisualização, não consegui encontrar nenhuma relacionada ao alinhamento do texto. Eu vi em uma demonstração que ele lida automaticamente com RTL, e ao colocar coisas usando View body, ele sempre centraliza automaticamente.

Há algum conceito que estou perdendo sobre o sistema de layout SwiftUIe, se não, como posso definir as propriedades de alinhamento do texto para o Text?

inokey
fonte

Respostas:

144

Você pode fazer isso por meio do modificador .multilineTextAlignment(.center).

Documentação Apple

vrwim
fonte
8
Existe algo para justificar o texto?
theMouk
85

Do SwiftUI beta 3 em diante, você pode centralizar uma visualização de texto com o modificador de quadro:

Text("Centered")
    .frame(maxWidth: .infinity, alignment: .center)
Jim Marquardt
fonte
39

Estava tentando entender isso sozinho como outras respostas aqui mencionam Text.multilineTextAlignment(_:)/ VStack(alignment:)/ frame(width:alignment:)mas cada solução resolve um problema específico. Eventualmente, depende do requisito de IU e uma combinação deles.


VStack(alignment:)

O alignmentaqui é para as vistas internas em relação umas às outras.
Portanto, a especificação .leadingassociaria todas as visualizações internas para que suas linhas principais estivessem alinhadas umas com as outras.

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

imagem


.frame

Em frame(width:alignment:)ou frame(maxWidth:alignment:), o alignmenté para o conteúdo dentro da largura fornecida.

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

As vistas internas estão alinhadas à esquerda, respectivamente, mas as próprias vistas estão alinhadas à direita, respectivamente VStack.

imagem


.multilineTextAlignment

Isso especifica o alinhamento do texto interno e pode ser visto melhor quando há várias linhas, caso contrário frame(width:alignment), a largura é ajustada automaticamente e é afetada pelos alignments padrão .

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

imagem


Testes com combinações:

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

imagem

staticVoidMan
fonte
1
Essa é uma resposta muito convincente. Obrigado. Vou considerar tornar essa resposta aceita também.
inokey
@inokey fico feliz em compartilhar minhas observações :) Mais tarde eu encontrei um artigo interessante aprofundando os alinhamentos de vista em geral: Guias de alinhamento em SwiftUI
staticVoidMan
cara de coisas incríveis. O SwiftUI realmente evoluiu desde que eu postei essa pergunta originalmente.
inokey
17

Na verdade, eu tive o problema de alinhar o texto em uma única linha. O que descobri para funcionar é o seguinte:

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

Se você combinar isso com o parâmetro de largura do quadro, você pode obter uma boa formatação de bloco de texto para rótulos e tal.

Lekyaira
fonte
14

Eu acho que SwiftUIquer que usemos invólucros como pilhas para essas coisas.

Portanto, em vez de escrever algo como Text("Hello World").aligned(.leading), o seguinte é encorajado:

VStack(alignment: .leading) {
    Text("Hello World")
}
Fredpi
fonte
1
Portanto, não posso simplesmente descartar um rótulo que é independente da pilha?
inokey
@inokey Não encontrei pelo menos um modificador para isso.
fredpi
Eu também não. Parece-me que sinto falta de algum tipo de conceito básico da SUI. Eu não posso nem colocar apenas a "visão" entre duas coisas, e dar uma cor, como se eles não tivessem um objeto simples a-la-uiview ali.
inokey
O modificador de quadro tem um parâmetro de alinhamento
EmilioPelaez
Parece bobagem ter que fazer (embora funcione). Onde você ouviu que isso foi incentivado?
MobileMon
6

Se você quiser manter a largura constante do Texto, o ".multilineTextAlignment (.leading)" não terá efeito até que haja apenas uma linha de texto.

Esta é a solução que funcionou para mim:

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


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

Uso:

Text("Hello").leftAligned().frame(width: 300)
Kamil Zaborowski
fonte
5

Precisamos alinhar o texto e não a pilha em que está. Assim, ao chamar multilineTextAlignment(.center)e definir os limites de linha, posso ver os textos alinhados ao centro. Não sei por que tenho que definir os limites da linha, pensei que expandiria se você tivesse um texto grande.

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

Você pode definir o alinhamento para Vertical stackView como líder. Como abaixo

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

insira a descrição da imagem aqui

Kathiresan Murugan
fonte
0

Eu gostaria de usar a visualização Spacer () para alinhar o bloco de texto. Este exemplo mostra o texto no lado final:

                HStack{
                    Spacer()
                    Text("Wishlist")
                }
Oleksii Radetskyi
fonte