One of many things that make SwiftUI great is the ability to combine views. The template code when you create a new SwiftUI view contains the following:
struct ContentView: View {
var body: some View {
Text("Place Holder")
}
}
The body variable is expecting some View. In the example above we are returning a Text view which contains a string “Place Holder”. If you preview this in the canvas you will see the words “Place Holder”, without quotes, in the centre of the view.
Swift provides the ability to combine views so that more views can be combined in to one and then returned. In our Stacks tutorial we explain this. In short, you can combine views in to a HStack, VStack, or ZStack and return the stack as one view.
As well as combining the provided views such as Text, List, Button, etc… we can also use custom views and combine the custom views with our view. This has a few benefits, some of which are that we can break down code in to smaller chunks allowing these smaller views to be used elsewhere in our project. If you compare the Text view, you can use it multiple times in your view, and then use it in other views. Our custom view can also do the same.
Example
To explain this process visually, we will create a List view that has a number of cells. Rather than design and place the code for those cells in to our content view, we will create a new SwiftUI file called “MessageOverviewView.swift” and then combine that with out content view class.
Create a new SwiftUI File
Create a new SwiftUI file and call it MessageOverviewView.swift. When created, open up the file.
Our MessageOverviewView SwiftUI file will define what a single cell looks like in a List. We will design it to be similar to an email app where we have a From field, a subject field, a snippet from the first sentence of the email, and the time/date the message was received.
To accomplish this, we first need to visualise what the layout will be. We will pick a traditional layout with the date on the top right, and the rest of the information stacked on top of each other to the left.
In the view above we have a VStack. The top part of the stack has a HStack embedded with a Text view, Spacer, Text view layout. Below that is a Text view, and below that, another Text view.
We might begin with something as follows:
struct MessageOverviewView: View {
var body: some View {
VStack {
HStack {
Text("From")
Spacer()
Text("Date/Time")
}
Text("Subject")
Text("Snippet from first line of the body")
}
}
}
This gives us something to work with, but the from and date/time text fields are too close the edge, and the subject and snippet are centrally aligned when ideally, they would be pushed to the left.
Lets fix the padding first. In SwiftUI you can add padding to any view. In this case, we’ll add it to the whole of the VStack. To do this, add the .padding(10) attribute just after the closing curly brace for the VStack:
VStack {
HStack {
Text("From")
Spacer()
Text("Date/Time")
}
Text("Subject")
Text("Snippet from first line of the body")
}
.padding(10)
By specifying just a 10 (or nothing at all between the brackets) it applies the padding to all four edges. If you wanted to just add padding on the left side of the VStack, you can do .padding(.leading) for example.
If you preview the view on the canvas, the items should be pushed inwards a little and have a padding of 10 set on all four edges.
To fix the centrally aligned subject and snippet text views you need to set the alignment of the VStack to the left by modifying the declaration of that as follows:
VStack(alignment: .leading) {
Every item will now be aligned to the left of the screen with the exception of where we have the HStack and spacer which pushes the date/time to the far right of the view.
You will now see the above in the canvas. If you do not, check for any syntax errors and then press resume or try again at the top right of the canvas. Doing that will refresh the canvas.
The last part of setting up this view is changing font sizes a little to make it look less bland.
Command+click on the first Text view and select “Show SwiftUI Inspector…”. You can change font weight, font, colour, size, and a number of other things. Feel free to set this as to what looks best for you. I used the following attributes:
struct MessageOverviewView: View {
var body: some View {
VStack(alignment: .leading) {
HStack {
Text("From")
.font(.title)
Spacer()
Text("Date/Time")
.font(.footnote)
}
Text("Subject")
.font(.headline)
Text("Snippet from first line of the body")
.font(.body)
}
.padding(10)
}
}
This completes the MessageOverviewView.swift view.
Using Message View in Custom View
Open up the content view and replace the Text view with MessageOverviewView() as follows:
struct ContentView: View {
var body: some View {
MessageOverviewView()
}
}
The code sample above shows how MessageOverviewView() was used just like a Text view or any other view. We can simply just use it where we want.
Using a List
An email app isn’t up to much if it can only allow you to access one message from the inbox. What we need to do next is create the equivalent of a TableView. In SwiftUI, we use a List.
You can wrap a List around the message view, and then make a manual call several times to the message view as follows:
import SwiftUI
struct ContentView: View {
var body: some View {
List {
MessageOverviewView()
MessageOverviewView()
MessageOverviewView()
MessageOverviewView()
MessageOverviewView()
}
}
}
This will show five cells on the view, each with the template. But again, this isn’t how email apps work. We may have more or less than five views. We need to make the list dynamic rather than using a List that is static.
struct ContentView: View {
var body: some View {
List(0 ..< 5) { item in
MessageOverviewView()
}
}
}
If we specify 0..<5 meaning it will count from 0 to 4 (ie, 5 times), we can then iterate over the list as follows. “item” in this instance would be the iteration of the loop which would be a number from 0 to 4.
In the next tutorial we’ll look at how we can iterate over an array of messages and then pass each message in to MessageOverviewView() so that each message overview shows some sample data.
Leave a Reply
You must be logged in to post a comment.