In this small tutorial I want to show you how you can create a simple card in SwiftUI with a image on top and some small text underneath it. This tutorial is aimed at beginners who just started using XCode.
Prerequesits
- Mac with XCode 12 installed
- Experience in Swift programming not necessary but can make your life easier
Creating a new Project
When you start up XCode you should be greeted with a small splash screen showing all your previous projects on the right and and options to create new projects.
For this project we want to create a new Xcode project, which should be the first option on the left. This should launch XCode and present you with multiple dialogs to configure your project. If the splash screen doesn’t appear when you start XCode you can create a project by choosing File ‣ New ‣ Project… in the top menu bar, which will open the same dialog to configure a new project. In the configuration dialog choose the following options:
- Under Application choose App and click Next
- Give your App a name in the Product Name field, I will call mine “ImageCard”
- Make sure Interface is set to SwiftUI and the Lifecycle to SwiftUI App
- confirm with Next
- A new dialog will open up where you can choose a location on your desktop to save your project, select a location and click Create
Understanding XCode
After the project is created you should see something similar to the screen shown below. Instead of explaining XCode in all its depth we will just quickly cover the main parts we need for this project to get started.
- On the left side you should see your project structure with all the files. The ContentView.swift is the file that contains all the UI elements that will show up as the main screen of the app. This file is also where we will start working in.
- Right beside that is the Editor. Here we will add our SwiftUI code, which will then be previewed on the right side of the editor.
- The preview is currently not running, but you can click on the “Resume” button in the top which will start the preview.
- Additionally in the top bar you can choose diffferent devices to preview your UI on smaller or bigger screens.
After clicking on “Resume” in the preview window, XCode will load the preview (which may take especially in the beginning a few seconds). After it finished loading you should see a white background with the, to most programmers very familiar, “Hello World” text.
Creating the Design
Before we dive right in we should take a look at what we actually want to build and how we can structure it. The UI element we want to create is relativly simple. We want to create a card with rounded corners, an image on top and some text underneath.
Creating the Text part of the Card
Lets start with the text first, after our initial View already has one text we can reuse this. In the final card we want to have two texts, one above the other. To do so, we can use a VStack.
Hold down command ⌘ and then left click on the Text element in the code. This will open up a small pop up window where you can choose “Embed in VStack”.
This shouldn’t have changed much, except that there is now a VStack element surrounding our Text element. A VStack can contain multiple views, which means we can add another Text to it right below the first.
In the code do the following:
- remove the padding from the Text and change the text from “Hello World” to “Morning Workout”
- add a second Text and change it to “10 min”
The final code should look like this:
So far so good, but we want to add a small clock in fron of the second text. We can easily do this by embedding it into a HStack this time. A HStack contains multiple elements like a VStack but it will put them next to each other. Press command ⌘ and left click on the second text, then choose HStack or edit the code directly. Next we want to create a Image and use one of the system icons Apple provides for us. Add Image(systemName: “clock.arrow.circlepath”) before the Text element in the HStack. The preview and code should now look like this:
The two final things we want to change is make the text align left and change the color and general look of it a bit. Lets start by making all of the elements align left. Left click on the VStack in the code and on the right side right beside the preview we can change some properties including the alignment:
Change the alignment to left and all the elements should nicely align on the left side. In the code you should see the change too, so next time you can either directly add in the code alignment: .leading or in the properties again.
There is a little bit too much space between the clock icon and the “10 min” text, so lets go ahead and click on the HStack and in the properties on the right change “Spacing” to 4.
Next lets change the look of the text a bit more. The text on top should be a bit bigger. Select the text, and in the settings on the right change the Font to headline.
The clock and the second text should both be gray. We could apply the colour to both elements but they are nicely encapsulated in the HStack so can just apply the colour to the full HStack by adding .foregroundColor(.gray) after the closing bracket of the HStack. Your Code and the preview should now look like this:
With this we finished the design of the text. Lets just nicely add it to a new view the clean up the main body a little bit.
- Select everything inside the body and use command ⌘ and X to cut it out.
- Create a new variable view underneath the body: var cardText: some View {} and paste everything with command ⌘ and V inside the currly brackets
- Lastly add cardText to the original body view. The preview should still look the same but we should have now a cleaner code
Creating the Image part of the Card
For the image part we first need a placeholder image that we can use to try out the design. I like to use the site UnSplash, all their photos you can use for free. On the page you can search for a specific topic and it will show you all the different pictures photographers uploaded to that topic. I searched for Workout and choose a picture from Emily Sea. As soon as you found a picture you like click on it and download it.
Back in XCode open up the Assets.xcassets and drag and drop your image in the list underneath AccentColor and AppIcon.
Lets get back to our ContentView.swift and add this above the Text we already created. To add two elements above each other we can again just use a VStack.
- Sourround cardText in the body view with a VStack
- add an Image before cardText and pass the name of your image
For example, my image is called morning-workout in the asset folder, therefore, I added Image(“morning-workout”). This should look like this:
If you look at the preview, you will see that the result is not directly what we want, as the image will probably take over the whole screen. To avoid this we just have to add some size information to the Image element. Add
- .resizable() and
- .frame(width: 200, height: 200)
Which will show the image right above the text in a nice square. If your image is not square you might want to choose a different size, by replacing the 200 x 200.
The text is underneath the image but doesn’t seem to align very well with the picture. To fix this select the VStack sourrounding the Image and the cardText and change its alignment to .leading. This worked but now the text is directly at the border or the image. Lets add a bit space with some padding. Simple add .padding(.horizontal, 8) after cardText.
Putting it all together
We have the text and the image now we just want to add it together so it looks more like a card. First of we want to add the rounded corners to our card and a shadow around it, to lift it up from the background.
For the rounded corners we can use .clipShape(RoundedRectangle(cornerRadius: 24.0) on the VStack containing the image and the card text. We can pass any kind of shape to the clipShape function and it will use it as a mask to the underlying objects.
This looks already pretty good, but we can’t really see the rounded corners at the bottom of the card, as the color behind the text and the background color are the same. Let’s add some shadow to change that. Again to the VStack we simply add .shadow(radius: 8) after the clipShape(). When previewing the result you will see that the text doesn’t have a shadow. This is because the text doesn’t have any background to throw a shadow. This is easily fixed by adding a white background color with .background(Color.white) to our card VStack.
Now we are nearly done. The only thing that is off is that there is basically no space from the text to the bottom of the card. We can quickly change that by adding some padding to the bottom to the HStack that holds the clock icon and the gray text. Add .padding(.bottom, 16) to the HStack and also add 16 spacing to the VStack holding the Image and the card to increase the distance between them too.
Finishing Off
We finished the design and now to finish this project we can move all the code in a separate file. This will allow us to reuse our card and have, for example, multiple cards next to each other.
To create a new SwiftUI file, go to File ‣ New ‣ File… or press command ⌘ and N. This will open up a small dialog window again, where we can choose which kind of file we would like to create. Select SwiftUI View in the User Interface section and click Next.
In the next window you can give it a name, I named it “ImageCard” and after confirming that you will have a new SwiftUI file in your project.
Now lets go back into ContentView.swift and copy over the cardText view and add it inside the ImageCard view after the closing bracket from the body view:
Now we do the same for the content of the body. Back in the ContentView.swift copy the content from the body view and replace the Hello World text in the body of the ImageCard with it.
To see the card now again in the ContentView.swift just add ImageCard() in the body. Our main view is now clean and we can easily elements without getting confused or accidentally changing our card.
Conclusion
First of all, congratulations if you made it until here! 👍
There is still a lot we can add to further improve our code. For example, passing the card title, subtitle and image name to quickly create new cards. But I think for this tutorial we did enough. I hope you enjoyed it!
If you have any ideas or comments about this tutorial or would like to see a tutorial about something else let me know! 😊