Creating a Fullscreen Background Image in SwiftUI — Beginner Tutorial
Hi my name is Izzy and in this tutorial I will show you how you can add a fullscreen background image to your SwiftUI app with overlaying elements. This tutorial is aimed at beginners with step-by-step instructions to follow along.
Prerequesits
- Mac with XCode 12 installed
- Experience in Swift programming not necessary but can make your life easier
The Concept
Before we dive right in, I want to show you the final design. Having an idea of the final design makes writing the code in SwiftUI much easier.
As an example app we will work on a screen for a travel app, but not just any travel app! We will create a screen for a space travel app 🚀.
The screen is actually rather simple: We have one background image that spans over the whole screen and we have some text overlaying it, which is separated by two horizontal divider.
There are three things in this screen, which I won’t cover in this tutorial but in following tutorials:
- SFSymbols and Shapes
- Custom Fonts
- Custom Shapes (arrow)
All of these are a little bit more advanced and therefore deserve their own tutorial.
Getting Started
Open up XCode and you should be greeted by a small Splashscreen, which allows us to create, for example, a new project, or continue working on one of our existing projects. For this tutorial we will create a new XCode project.
This will open up XCode and greet us with a small row of dialog windows to configure our project further. First of, we have to choose the platform we want to develop our app for. In this case we will go for an iOS App.
Select App and then click on Next. In the next window we will be asked for a Product Name, this will be the name of our app. I will call my app “Space Travel”. For the organization identifier, you can choose what ever you want. If you have your own website, like “example.com” you could write “com.example” as the identifier. Additionally, make sure you have the Interface and Life Cycle set to SwiftUI and the Language set to Swift.
After clicking Next we will be asked for a location where we want to save our project and then XCode will generate all the files we need to get started. Your screen should now look similar to the following:
- on the left side we have all our project files
- beside it on the right we have the area where we can code
- and next to that is the preview area. Here we just have to click on “Resume” (which can load a bit for the first time) and then we will see a preview of our app
- in the top bar you can also change the device on which you want to preview your app
The Design
Fullscreen Background Image
Before we can add a background image to our app, we need the picture. I like to use the website unsplash.com: It has millions of 100% free to use pictures, perfect for our app. I searched for “Space” and found a great picture from Alexander Andrews. You can download the same picture here.
Download the picture and save it somewhere where you can find it easily again. Now in XCode open up Assets.xcassets and drag your picture from Finder underneath AppIcon and AccentColor. A good idea would also be to rename it to something you can easily type and remember, I went for “moon-background”.
Lets go back into ContentView.swift so we can finally add our picture. There are multiple ways how we can add a picture in SwiftUI. For example, if you are familar with writting SwiftUI apps you might know exactly what code snippet you need. If you are just starting out, it might be easier getting the element you want from the library.
First click the little plus sign in the top bar to open up the view library. This will open a small modular window with all the different kind of views that we can directly use. Each of the views also has some text and explanation on the right that helps us setting everything up.
Search for image and then scroll down a bit in the text to see the example usage. You can now either drag and drop the image into your code or onto the screen to place it relative to the text, or we can just go ahead and write the code by ourself, now that we know how to add an Image.
Let’s remove the Text(“Hello World”).padding() and instead add our image. The string that we pass as an argument is the name of the image that we defined when we added it to Assets.xcassets in my case “moon-background”.
The image covers nicely all of the screen but it seems to be even bigger than the actual screen and some parts of the image are not even visible. If we go back into the library we can find out pretty quickly why:
In the example, there are two more functions added to the image. The first one resizable() allows the image to change size and squeezes it into the screen. This ignores the original aspect ratio of the image which is not necessarily nice. Thats why we add as a second function the aspectRatio() function. This function tells SwiftUI to keep the original aspect ratio of the image. Here we can pass two arguments:
- .fit: fits the image into the parent container and leaves white spaces if necessary
- .fill: fills the parent container with the image and cuts off parts of the image if necessary → this is the one we want to use in this case
Our code should look like this after adding the functions:
If you check the preview you will see that the image is already nicely stretching over the screen but there are still two white arrays at the top and bottom which are in the way. These are called “Safe Area” and we can tell our image to ignore them, with the function .edgesIgnoringSafeArea(.all).
With that our image will fully stretch over the screen 😊. Your preview should look similar to this:
And the final code for the image should look like this:
Understanding Stacks in SwiftUI
Before we can place the text on the image we need to understand how stacks works in SwiftUI and how they can help us organize views. There are three different Stacks we can use: HStack (horizontal), VStack (vertical) and ZStack.
- HStack: Places multiple views next to each other
- VStack: Stacks views in a vertical order above each other
- ZStack: Allows to overlay a views with others
We want the text to be above the picture, which is a prefect use case for the ZStack. The text and dividers are all vertically underneath each other, prefect for a VStack.
Text & Dividers
To add the text above the image we need a ZStack. We can either search for it in the library like we did with the image or use a neat little shortcut.
Press command ⌘ and left click on the Image in your code. This will open up a small pop up window which allows us to embed our image in a new view. Here we can choose Embed in Zstack, which will wrap the ZStack around our Image.
Now we can add a Text view right underneath the image code but in the ZStack{} and it will appear on top of our image. Simply add Text(“Space Travel”) after the .edgesIgnoreSafeSpace(.all) function.
The text is perfectly on top of the image but we want another longer text underneath it surrounded by two dividers. Let command ⌘ and left click on the text and embed it into a VStack, so we can add further elements beneath it. Then add Divider() for a horizontal line, another Text(“…”) and in the end one more Divider(). The code should look like this:
If you check the preview, you might be a bit disappointed. Right now it doesn’t really look like a nice app. To be precise there are multiple issues, but as you will see, all of them we can fix very easily and fast.
What we need to do:
- Fix the problem of text running out of the screen
- Change Text and Divider color to make them more visible and easier to read
- Change the alignment of the text to align it all on the left bottom
Lets start with the biggest problem: the text seems to be ignoring the end of the screen and just leaves the screen. If you select the background image you can see really fast why. When you select the background image there should be a blue frame indicating the frame of the image (also shown in the screenshot above).
The blue frame is basically the space where all other items will be added to. This means the text will stretch from the left side of the blue frame to the right. To fix this we just have to tell the frame of the picture to fit to the width of the screen, and we can do this simply by adding .frame(minWidth: 0, maxWidth: .infinity) to our image.
Now our text is nicely wrapped in the screen. Maybe a bit too nicely. Right now our text really goes from one side of the screen to the other. Lets add a bit of space to the edges, by adding a horizontal padding. We can add padding to every view, this means we could add it just to a specific text or to the whole block by adding it to the VStack. Simply add .padding(.horizontal, 24) after the closing curly bracket of the VStack and we should have some nice space between the text and the screen sides.
Lets work on the text appearance next. Similar to the padding we can change the color for each element separately. In this case, however, we want all of them to have the same color, so we can just assign the VStack a white forground color. Add .foregroundColor(.white) to the VStack and the text should appear in white.
You may notice that the color of the Dividers is not changed by this. To change the color of a divider we need to change their background color. If we would apply a background color to the VStack, it would apply a color to the whole frame. This would mean we wouldn’t be able to read the text anymore if there would be a white background. So we will add the white background only to our Dividers by adding .background(Color.white) [Line 11 & 13].
The last thing that is missing is the alignment. First left click on the VStack and on the right side in the properties change the alignment to left.
Next add a Spacer() before the first Text view in the VStack to push the text to the bottom. To lift the text a bit up, we can add another padding to the bottom of the VStack, by adding .padding(.bottom, 64) after our horizontal padding. We can also add some trailing padding to both of our Dividers which will make them shorter and leave some space to the right. Just add .padding(.trailing, 128) to both of them.
Finally, we can adjust the text a bit to finish our design for this tutorial. If you select one of the text, you can see multiple options in the properties pane on the right. Lets change the headline to a Large Title font and its weight to Light. For the longer text underneath, we can just change the weight to Light.
And this is it:
Congratulations! 👏 If you managed to follow along, good job and I hope this gives you a better understanding of SwiftUI and how you can create your own designs. Here you can see the full code:
Next Tutorials
I will write a few more tutorials to finish this design and will link them in this article as soon as I publish them. Topics will include:
- working with SF Symbols and Shapes: Published, view here
- adding custom fonts
- creating custom Shapes
I hope you enjoyed this tutorial and if you have any comments about the general layout of the tutorials or any whishes for future tutorials feel free to let me know in the comments. 😊