Components: Text, VStack ed HStack in SwiftUI
SwiftUI mette a disposizione un insieme di elementi chiamati Components che ti permetteranno di assemblare l'interfaccia della tua app utilizzando dei blocchi preconfezionati.
Un esempio di component potrebbe essere List
che permette di creare feed come la homepage di Instagram, Image
per renderizzare immagini locali e remote o ScrollView
per creare pagine che l'utente potrà scrollare.
In pratica, SwiftUI si occupa di gestire la User Interface (da qui UI
) mentre tu dovrai preoccuparti solamente della logica e funzionamento dell'app.
Noi siamo partiti dal componente Text
che ci ha permesso di visualizzare del testo su schermo:
Text("Welcome to LearnWithPeppe")
Oggi incontreremo due nuovi componenti di SwiftUI che saranno fondamentali per le tue interfacce: VStack
ed HStack
.
VStack
e HStack
sono contenitore che ti aiuteranno a disporre views in verticale o orizzontale.
A fine lezione sarai in grado di interpretare il codice della tua ContentView
, scoprirai cos'è il body
e come creare nuove var
o variabili in Swift.
Ma bando alle ciance, apri o crea un progetto SwiftUI e poi entra nel file ContentView
.
Let's start!
var e body di una View
Ogni View
quindi ogni pezzo di interfaccia ha una struttura del codice che è uguale indipendentemente dalle funzionalità che offre.
Da un primo sguardo alla ContentView
possiamo notare come all'interno delle prime parentesi graffe c'è una linea che recita:
var body: some View {
}
Cosa significa?
Spezziamo la frase in due parti:
-
var body
La parola
var
è una parola del linguaggio Swift e significa variabile. Una variabile è un contenitore di informazioni. Espanderemo questo concetto nelle prossime lezioni.body
è il tag del contenitore. Una sorta di label o etichetta che permette a Swift ed a noi sviluppatori di capire cosa c'è dentro quel contenitore.
-
: some View
I due punti stanno ad indicare che la variabile potrà contenere solamente un tipo di informazione ben specifico. Un po' come scrivere nell'etichetta di un barattolo "Qui puoi mettere solo farina Gluten Free" (il mio partner sarà super contento di questo riferimento 😂).
some View
puoi leggerlo come "dentro la variabile posso mettere qualsiasi tipo di View".
Infine, ciò che c'è dentro le parentesi graffe rappresenta il contenuto della var body
.
In questo momento dentro il nostro body
c'è un Text
, il Text
è un Component di SwiftUI ed essendo una View
può essere inserito dentro il body della ContentView.
📌 Regola: Ogni
View
deve obbligatoriamente avere unavar body
per essere creata ed utilizzata.
Creare una nuova var
Adesso che sappiamo che dentro ad una variabile possiamo inserire un pezzo di interfaccia, proviamo a crearne una nuova.
Subito sotto la var body
, ovvero sotto la sua parentesi graffa, aggiungi una nuova var
. Chiamiamo questa var myText
e come tipo di dato usiamo Text
invece che some View
:
var myText: Text {
Text("My new Text")
}
Cosa cambia adesso che abbiamo usato il Text
invece che il some View
?
Mentre some View
ci permette di utilizzare qualsiasi tipo di View, specificando Text
siamo obbligati ad usare solamente quello. Infatti, se aggiungi il padding()
vedrai che Xcode ti segnalerà un errore:
🚨 Cannot convert return expression of type 'some View' to return type 'Text'
Nello specifico, aggiungere il padding
(vedremo meglio cosa fa nella prossima lezione), modifica il Text
trasformandolo in una some View
(puoi leggerlo "generica View
") ma dato che la var myText
vuole un Text
ecco che Xcode ci blocca dall'eseguire il codice e ci segnala l'errore.
Vedremo l'importanza di specificare il type corretto nelle prossime lezioni, oggi ti volevo semplicemente dare un piccolo assaggio.
Quindi, rimuovi il type Text
e usa invece some View
e l'errore dovrebbe scomparire.
Come usare una var all'interno del body
Avrai sicuramente notato come la nuova variabile non compare all'interno della preview. Questo succede perché in SwiftUI l'unica variabile adibita al rendering è il body
.
Tutto ciò che sta all'esterno non verra riportato all'interno del canvas e di conseguenza dell'app.
Quindi, come facciamo ad usare quella var myText
?
La label di una variabile può essere passata all'interno di un'altra.
Infatti, se rimuovi il Text dal body e metti myText, vedrai che SwiftUI prenderà il contenuto di quella variabile e lo passerà su schermo:
⚠️ Nel caso in cui il Canvas dovesse mostrare un messaggio che recita: Automatic preview updating paused, clicca su Resume per farlo ripartire.
Creare nuove variabili di tipo some View
all'interno delle tue view sarà uno dei tanti modi che ti permetterà di organizzare il codice sopratutto quando le tue interfacce cominceranno a contenere diversi componenti.
VStack
Adesso che abbiamo capito come funziona il body e come creare una nuova variabile che contiene una View, vediamo il primo nuovo componente chiamato VStack
o Vertical Stack.
Una VStack
è un contenitore verticale di View
. La sintassi è relativamente semplice. VStack
parentesi graffe con all'interno le view che vuoi posizione in linea verticale:
VStack {
viewA
viewB
...
}
Vediamo subito come utilizzare questa VStack
.
Inserisci all'interno del body
la VStack
con all'interno il myText
più un nuovo Text
:
var body: some View {
VStack {
Text("This is a VStack")
myText
}
}
⚠️ Nel Text che ho inserito dentro la VStack non ho messo la .padding(), per il momento non è importante ma come penso si possa capire aggiunge un po' di margine su tutti i lati della view. Vedremo più nel dettaglio nelle prossime lezioni.
Abbastanza intuitiva questa VStack
no? Eventualmente lascia un commento in fondo alla lezione.
Spacer
Al momento questa VStack
è posizionata al centro dello schermo. Diciamo non un bel vedere. Per fortuna esiste un componente chiamato Spacer
che ti permetterà di occupare lo spazio non usato verticalmente o orizzontalmente.
Più facile a farsi che a dirsi.
Puoi aggiungere lo spacer dentro la tua VStack
creandolo utilizzando questa sintassi:
Spacer()
Et voilà! Tutto viene spostato verso l'alto e lo Spacer occupa lo spazio non utilizzato.
🙋♂️ Question A: Cosa succede se sposti lo Spacer tra il Text ed il myText?
HStack
Se la VStack
permette di arrangiare elementi in verticale, la HStack
o Horizontal Stack ci permetterà di farlo in orizzontale.
HStack {
viewA
viewB
}
Proviamo a metterla all'interno della VStack
subito dopo la myText
ed aggiungiamo 3 Text
al suo interno:
VStack {
Text("This is a VStack")
myText
HStack {
Text("Tag1")
Text("Tag2")
Text("Tag3")
}
Spacer()
}
Ovviamente, nessuno ti vieta di innestare VStack
con HStack
o viceversa. Grazie a questi due elementi puoi ipoteticamente creare qualsiasi tipo di layout.
💡 Tip: Puoi mettere uno
Spacer
a destra o sinistra dellaHStack
per spostare gli elementi nella direzione opposta.
Bonus: Padding e clean code
Infine, riorganizziamo leggermente il codice e puliamo il contenuto della VStack in modo tale da avere un codice un po' più snello e facile da leggere.
💡 Tip: È una buona prassi di SwiftUI quella di lasciare il
body
quanto più clean possible in modo che quando ritorni su questo file ti verrà più semplice capirne il suo contenuto.
Potremmo infatti:
creare una nuova var chiamta header per visualizzare i primi due
Text
. Ricordati di metterli dentro una nuovaVStack
.Ed una
var
chiamata stacks in cui metter laHStack
.Queste etichette le sto scegliendo io immaginando che l'app avrà un header e dei tags. Ovviamente tu puoi decidere di chiamare queste variabli come ti pare, anche ciccio e caio 😂:
Ed infine, usiamo quel famoso .padding()
sulla VStack
contenuto dentro l'header in modo tale da creare un po' di spazio tra l'header ed i tags.
VStack {
Text("This is a VStack")
Text("My new Text!")
}
.padding()
Comunque non preoccuparti il padding() ed altre di queste funzionalità le vedremo nel dettaglio nella prossima lezione.
Stack Alignment
Al momento tutti gli elementi che abbiamo posizionato dentro una Stack vengono posizionati al centro ed ovviamente, in certi layout, non è del tutto conveniente.
Per fortuna, la VStack
o la HStack
può essere inizializzata (risentirai questo termine più in là) definendo il tipo di allineamento da utilizzare.
Come?
Ti basta aggiungere le parenti tonde subito dopo il nome del component per poi scrivere all'interno "alignment: .leading":
VStack(alignment: .leading) {
}
Devo per forza usare il punto?
Yes. Il punto nel linguaggio Swift, in questo caso, puoi leggerlo come "voglio utilizzare". Nell'esempio del leading puoi leggere la linea come: Crea una VStack
con alignment di tipo leading (sulla sinistra).
I valori di alignment per una VStack
sono:
leading
: sinistracenter
trailing
: destra
VStack(alignment: .leading) {
Text("Hello")
/// HStack necessaria per espandere
/// la view su tutto l'asse orizzontale
HStack {
Spacer()
}
Spacer()
}.padding()
🚨 Nota come nell'esempio ho dovuto aggiungere una
HStack
conSpacer
per far in modo che laVStack
occupasse tutto lo spazio orizzontale. Senza questo piccolo trucco anche con allineamento leading ilText
sarebbe stato renderizzato al centro. Prova a rimuovere laHStack
e vedi che succede.
Se per la VStack
l'allineamento influisce sull'asse orizzontale, per la HStack
è l'opposto. Infatti potrai utilizzare:
center
top
ebottom
firstTextBaseline
: allinea tutti gli elementi sulla linea inferiore della prima view della stack.lastTextBaseline
: l'opposto delfirst
.
HStack(alignment: .bottom) {
Text("Hello,")
.padding()
Text("Giuseppe")
}
In questo esempio, il primo Text ha del padding che allunga la HStack in verticale, con l'allineamento di tipo .bottom gli altri elementi vengono portato sulla linea inferiore della stack.
Ad ogni modo, non preoccuparti, vedremo meglio come utilizzare questi attributi nelle prossime lezioni.
Spacing
Infine, l'ultimo attributo di una VStack
ed HStack
che ti voglio mostrare si chiama Spacing
e permette di definire lo spazio tra gli elementi della stack.
È abbastanza intuitivo da usare e funziona esattamente come l'alignment
. All'interno delle parentesi tonde ti basta aggiungere "spacing: numero". Esempio:
HStack(spacing: 40) {
Text("Hello,")
Text("Giuseppe")
}
I due Text
verranno divisi da 40 punti di spazio.
Nel caso in cui volessi usare alignment e spacing allo stesso momento, prima inserisci l'alignment
ed infine lo spacing
. Dividi i due attributi con una virgola:
HStack(alignment: .center, spacing: 40)
Lo stesso potrai fare per la VStack.
Esercizio
Prima di lasciarci voglio metterti alla prova con un piccolo esercizio dove dovrai combinare Stack tra loro. Quello che devi fare è provare a ricreare il seguente layout:
Nel caso in cui dovessi avere qualche problema puoi trovare la soluzione in questo gist su Github.
Conclusione
VStack
ed HStack
ti accompagneranno da qui fino alla fine dei tuoi giorni 😂. Sono tra i componenti di SwiftUI che permettono di organizzare il layout della tua app e di conseguenza li ritroverai un po' ovunque.
Noi li abbiamo utilizzati usando Text
ma come puoi ben immaginare possono contenere qualsiasi tipo di View
e possono anche essere combinati tra loro. Infatti, spesso e volentieri, ti ritroverai a mettere VStack
dentro HStack
o viceversa per poter ottenere le UI più complesse.
Nella prossima lezione parleremo di Modifier ovvero di funzioni speciali di SwiftUI che permettono di applicare degli stili alle tue view.
Uno di questi è per l'appunto quel famoso padding()
che abbiamo visto fin dalla prima lezione e dalla lezione successiva finalmente capire come funziona.
Buona programmazione! 👨💻👩💻