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?

Respostas:



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)

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


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.


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

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)

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)

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


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")
                }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.