O deseño da interface de usuario é en gran medida unha cuestión de seleccionar os compoñentes de interface apropiados, decidir como se colocarán esas vistas na pantalla e logo implementar a navegación entre as diferentes pantallas e vistas da aplicación.
SwiftUI proporciona stacks ou contedores que sirven para organizar as vistas (botóns, campos de texto, imaxes…) dentro da interface, e, ademais, a forma en que o deseño desas vistas responde aos cambios de orientación e tamaño da pantalla
Un Stack
é un contedor de vistas que permite amontoar varias vistas unhas encima ou a carón doutras.
Podes elixir entre varios tipos de Stack
principais:
VStack
(vertical): amontoa as vistas unha encima doutra, de arriba cara abaixoHStack
(horizontal): amontoa as vistas unha á beira da outra, de esquerda a dereitaZStack
(profundidade): permite superpoñer vistas unhas sobre outras
VStack #
Un contedor VStack
amontoa as vistas unha encima doutra, de arriba cara abaixo:
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "goforward.10")
Image(systemName: "goforward.15")
Image(systemName: "goforward.30")
}
}
}
Neste exemplo, as tres imaxes aparecerán unha encima doutra, de arriba cara abaixo, tal que así:
O exemplo completo en Xcode:
HStack #
Un contedor HStack
amontoa as vistas unha á beira da outra, de esquerda a dereita:
struct ContentView: View {
var body: some View {
HStack {
Image(systemName: "goforward.10")
Image(systemName: "goforward.15")
Image(systemName: "goforward.30")
}
}
}
Neste exemplo, as tres imaxes aparecerán en liña, unha á beira da outra e de esquerda a dereita, tal que así:
O exemplo completo en Xcode:
ZStack #
ZStack
é un tipo de contedor que permite superpoñer vistas unhas sobre outras (no eixo Z -en profundidade-).
Con ZStack
, podes axustar a posición e o tamaño de varias vistas e controlar a orde en que se superpoñen entre si.
Vexamos un exemplo:
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Image("fotoPerfilDiego")
.resizable()
.scaledToFit()
VStack {
Text("Texto e fondo opaco")
.frame(minWidth: 100, minHeight: 40)
.foregroundColor(.white)
.background(.black)
.cornerRadius(4)
Text("Texto semitransparente (40% de opacidad)")
.frame(minWidth: 100, minHeight: 40)
.foregroundColor(.white)
.cornerRadius(4)
.background(.black)
.opacity(0.4)
Text("Texto con fondo semitransparente (40% de opacidad)")
.frame(minWidth: 100, minHeight: 40)
.foregroundColor(.white)
.cornerRadius(4)
.background(Color.black.opacity(0.4))
}
}
}
}
Embeber unha vista nun Stack #
Para incrustar un compoñente existente nun Stack
:
- Faino de xeito manual
- Ou pasa o punteiro do rato sobre o compoñente no editor para que se resalte, mantén pulsada a tecla
Command
no teclado e fai clic co botón esquerdo no compoñente. No menú resultante (figura inferior), selecciona a opción adecuada:
Stacks dentro de stacks #
Os deseños de considerable complexidade pódense deseñar simplemente incrustando stacks dentro doutros stacks, por exemplo:
struct ContentView: View {
var body: some View {
VStack {
Text("Resultados finacieiros").font(.title)
HStack{
Text("1º Trimestre").font(.headline)
VStack{
Text("Xaneiro")
Text("Febreiro")
Text("Marzo")
}
VStack{
Text("1.000€")
Text("2340€")
Text("780€")
}
}
}
}
}
Espazos entre vistas #
Para engadir espazo entre vistas, SwiftUI inclúe o compoñente Spacer()
.
O Spacer()
expándese e contráese de forma flexible ao longo do stack que o contén (noutras palabras, horizontal ou verticalmente) para proporcionar un espazo entre as vistas colocadas en cada lado, por exemplo:
struct ContentView: View {
var body: some View {
VStack {
VStack {
Text("Resultados financieiros").font(.title)
Spacer()
HStack{
Text("1º Trimestre").font(.headline)
VStack{
Text("Xaneiro")
Text("Febreiro")
Text("Marzo")
}
VStack{
Text("1.000€")
Text("2.340€")
Text("780€")
}
}
HStack{
Text("2º Trimestre").font(.headline)
Spacer()
VStack{
Text("Abril")
Text("Maio")
Text("Xuño")
}
VStack{
Text("4.500€")
Text("2.400€")
Text("3.480€")
}
}
}
}
}
}
Alignment
: aliñación das vistas dentro dun stack #
Podemos aliñar o contido dun stack no momento en que declaramos o stack.
En SwiftUI, os VStack
e HStack
teñen varias propiedades de aliñación para controlar como se aliñan as vistas contidas dentro do Stack
.
Algúns dos tipos de aliñación dos VStack
son:
alignment: .leading
: Aliña as vistas contidas dentro doStack
á esquerda.alignment: .trailing
: Aliña as vistas contidas dentro doStack
á dereita.alignment: .center
: Aliña as vistas contidas dentro doStack
ao centro.
Algúns dos tipos de aliñación dos HStack son:
alignment: .top
: Aliña as vistas contidas dentro doStack
na parte superior.alignment: .bottom
: Aliña as vistas contidas dentro doStack
na parte inferior.alignment: .firstTextBaseline
: Aliña as vistas contidas dentro doStack
coa primeira liña de texto,alignment: .lastTextBaseline
: Para aliñalas coa última liña de texto.
É importante ter en conta que a aliñación se refire só ao contido dentro do Stack
, non afecta as dimensións do Stack
en si.
Tamén se poden especificar aliñacións cun valor de espazado. Neste exemplo establécese o espazado entre os elementos do VStack
en 10 e alíñase o contido do VStack
ao centro:
VStack(alignment: .center, spacing: 10) {
Text("Texto 1")
Text("Texto 2")
Text("Texto 3")
}
Vamos a ver outro exemplo en Xcode:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .center, spacing: 20) {
VStack {
Text("Lorem ipsum dolor sit amet")
Text("Aliñación por defecto")
Text("Lorem ipsum dolor sit amet")
}
.border(Color.red)
VStack(alignment: .leading) {
Text("Lorem ipsum dolor sit amet")
Text("Aliñación esquerda")
Text("Lorem ipsum dolor sit amet")
}
.border(.black)
VStack(alignment: .trailing) {
Text("Lorem ipsum dolor sit amet")
Text("Aliñación dereita")
Text("Lorem ipsum dolor sit amet")
}
.border(.green)
HStack(alignment: .bottom) {
Text("Lorem ipsum dolor sit amet")
Text("Aliñación abaixo")
Text("Lorem ipsum dolor sit amet")
}
.border(.yellow)
HStack(alignment: .top) {
Text("Lorem ipsum dolor sit amet")
Text("Aliñación arriba")
Text("Lorem ipsum dolor sit amet")
}
.border(.black)
}
}
}
Padding
: espazo entre vistas #
En SwiftUI, os VStack
e HStack
teñen varias propiedades de padding para controlar o espazo ao redor das vistas contidas dentro do Stack
. En todas as propiedades lle podes especificar un valor do espazo en puntos (por exemplo, padding(.all, 20)
).
Algúns dos tipos de padding son:
padding()
oupadding(.all)
: Agrega un espazo uniforme ao redor de todas as vistas contidas dentro doStack
.padding(.leading)
: Agrega espazo só á beira esquerdo doStack
.padding(.trailing)
: Agrega espazo só á beira dereito doStack
.padding(.top)
: Agrega espazo só na parte superior doStack
.padding(.bottom)
: Agrega espazo só na parte inferior doStack
.padding(.horizontal)
: Engade espazo aos lados esquerdo e dereito doStack
padding(.vertical)
: Engade espazo arriba e abaixo doStack
.
É importante ter en conta que o padding non afecta o tamaño das vistas contidas dentro do Stack
, só afecta o espazo ao redor das vistas.
Neste exemplo establécese o espazado entre os elementos do VStack
en 10 e engádese un padding de 20 puntos ao redor de todo o Stack
:
VStack(alignment: .leading, spacing: 10) {
Text("Texto 1")
Text("Texto 2")
Text("Texto 3")
}
.padding(.all, 20)
Vamos a ver outro exemplo en Xcode:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .center, spacing: 20) {
VStack {
Text("Sen padding (marxen interno)")
}
.border(Color.red)
VStack {
Text("Padding por defecto")
}
.padding().border(Color.black)
VStack {
Text("Padding 30 en todos os lados")
}
.padding(.all,30).border(.yellow)
VStack {
Text("Padding esquerdo + marxen por defecto")
}
.padding(.leading).border(.blue)
VStack {
Text("Padding dereito + marxen por defecto")
}
.padding(.trailing).border(.green)
VStack {
Text("Padding horizontal")
}
.padding(.horizontal).border(.black)
VStack {
Text("Padding vertical")
}
.padding(.vertical).border(.red)
}
}
}
Nº máximo de fillos #
Os stacks están limitados a 10 vistas descendentes directos.
Se un stack supera o límite de 10 fillos, as vistas se terán que incrustar en outros stacks.
Límites e prioridade de texto #
De forma predeterminada, un HStack
tentará mostrar o texto dentro dos seus fillos de vista de texto nunha soa liña, tal e como vedes no seguinte exemplo:
struct ContentView: View {
var body: some View {
HStack{
Image(systemName: "bus")
Text("Horario de buses:")
Text("Maceda")
}
.font(.title)
}
}
Que pasa se o Stack non ten espacio? #
Se un Stack
non ten suficiente espazo, o texto envolverase automaticamente en varias liñas cando sexa necesario:
Limitar o número de liñas #
Para limitar o Stack
a que teña unha única liña empregamos o seguinte modificador sobre o HStack
.lineLimit(1)
:
struct ContentView: View {
var body: some View {
HStack{
Image(systemName: "bus")
Text("Horario de buses:")
Text("Ida a Maceda")
}
.font(.largeTitle)
.lineLimit(1)
}
}
Prioridade de textos #
Dentro dun mesmo Stack
, pode ser o caso de que varias vistas de texto non collan dentro del.
Mediante o uso do modificador .layoutPriority()
engadimos a cada texto a súa prioridade, de xeito que canto maior sexa o número, maior será a prioridade do deseño.
Así, supoñendo que o nome da cidade de destino do bus sexa máis importante que o texto «Horario de buses:», o Stack
de exemplo podería modificarse da seguinte maneira:
A maiores… Lazy Stacks #
É posible que un Stack
conteña grandes cantidades de vistas, de xeito que ao utilizar HStack
e VStack
, o sistema creará todas no momento da inicialización: Isto pode conducir a un problema no rendemento da app.
Para abordar este problema, SwiftUl tamén proporciona vistas de pila verticais e horizontais «preguiceiras».
Estas vistas (chamadas LazyVStack
e LazyHStack
) utilizan exactamente a mesma sintaxe de que os Stacks
vistos anteriormente, pero están deseñadas para crear só vistas secundarias segundo sexa necesario.
Por exemplo, a medida que o usuario se despraza por un Stack
, as vistas que actualmente están fóra da pantalla só crearanse unha vez que se acheguen ao momento de ser visibles para o usuario.
Unha vez que esas vistas saen da área de visualización, SwiftUl libera esas vistas para que xa non tomen recursos do sistema.
Ao decidir se usar pilas tradicionais ou preguiceiras, xeralmente recoméndase comezar usando as pilas tradicionais e cambiar a pilas preguiceiras se se atopan con problemas de rendemento relacionados cun gran número de vistas.