Alineación de texto SwiftUI

90

Entre las muchas propiedades de la Textvista, no pude encontrar ninguna relacionada con la alineación del texto. He visto en una demostración que maneja automáticamente RTL, y cuando coloca cosas usando View body, siempre lo centra automáticamente.

¿Hay algún concepto que me falta sobre el sistema de diseño SwiftUIy, si no es así, cómo puedo establecer las propiedades de alineación del texto Text?

inokey
fuente

Respuestas:

144

Puede hacer esto a través del modificador .multilineTextAlignment(.center).

Documentación de Apple

vrwim
fuente
8
¿Existe algo para justificar el texto?
theMouk
85

Desde SwiftUI beta 3 en adelante, puede centrar una vista de texto con el modificador de marco:

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

Estaba tratando de entender esto yo mismo, ya que otras respuestas aquí mencionan Text.multilineTextAlignment(_:)/ VStack(alignment:)/ frame(width:alignment:)pero cada solución resuelve un problema específico. Eventualmente, depende de los requisitos de la interfaz de usuario y una combinación de estos.


VStack(alignment:)

El alignmentaquí es para las vistas interiores en respectivas entre sí.
Por .leadinglo tanto, especificar asociaría todas las vistas internas para que sus líneas principales se alineen entre sí.

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

imagen


.frame

En frame(width:alignment:)o frame(maxWidth:alignment:), alignmentes para el contenido dentro del ancho dado.

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

Las vistas internas están alineadas en avance entre sí, pero las vistas en sí mismas están alineadas en la parte posterior con respecto a VStack.

imagen


.multilineTextAlignment

Esto especifica la alineación del texto en el interior y se puede ver mejor cuando hay varias líneas, de lo contrario sin una definida frame(width:alignment), el ancho se ajusta automáticamente y se ve afectado por los valores predeterminados 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))

imagen


Pruebas con combinaciones:

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

imagen

staticVoidMan
fuente
1
Esa es una respuesta muy convincente. Gracias. También consideraré hacer de esta una respuesta aceptada.
inokey
@inokey me complace compartir mis observaciones :) Más tarde encontré un artículo interesante que profundizaba más en las alineaciones de vistas en general: Guías de alineación en SwiftUI
staticVoidMan
hombre de cosas increíbles. SwiftUI realmente evolucionó desde que publiqué originalmente esa pregunta.
inokey
17

De hecho, me encontré con el problema de alinear el texto en una sola línea. Lo que encontré que funciona es esto:

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

Si combina esto con el parámetro de ancho del marco, puede obtener un buen formato de bloque de texto para etiquetas y demás.

Lekyaira
fuente
14

Supongo que SwiftUIquiere que usemos envoltorios como pilas para esas cosas.

Entonces, en lugar de escribir algo como Text("Hello World").aligned(.leading), se recomienda lo siguiente:

VStack(alignment: .leading) {
    Text("Hello World")
}
fredpi
fuente
1
Entonces, ¿no puedo soltar una etiqueta que sea independiente de la pila?
inokey
@inokey No encontré un modificador para esto al menos.
fredpi
Yo tampoco. Me parece que extraño algún tipo de concepto básico de SUI. Ni siquiera puedo dejar caer como la "vista" entre dos cosas y darle un color, como si no tuvieran un objeto simple a-la-uiview allí.
inokey
El modificador de marco tiene un parámetro de alineación
EmilioPelaez
Parece una tontería tener que hacerlo (aunque funciona). ¿Dónde escuchó que esto fue alentado?
MobileLun
6

Si desea mantener un ancho constante para el texto, ".multilineTextAlignment (.leading)" no tendrá ningún efecto hasta que solo haya una línea de texto.

Esta es la solución que funcionó para mí:

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
fuente
5

Necesitamos alinear el texto y no la pila en la que se encuentra. Entonces, al llamar multilineTextAlignment(.center)y establecer los límites de línea, puedo ver los textos alineados en el centro. No sé por qué tengo que establecer los límites de línea, pensé que se expandiría si tiene un texto grande.

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

Puede establecer la alineación para Vertical stackView como líder. Como abajo

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

ingrese la descripción de la imagen aquí

Kathiresan Murugan
fuente
0

Me gustaría usar la vista Spacer () para alinear el bloque de texto. Este ejemplo muestra texto en el lado final:

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