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?

Respuestas:



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)

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


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.


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

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)

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)

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í


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")
                }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.