Hey, guys. 1
Welcome to another lesson on SwiftUI. In this module, 2
We're going to be creating the Dicee app. And in the process, we're going to look at how you can create 3
an app with functionality using SwiftUI. 4
In addition, we're going to get more practice creating layouts using SwiftUI, as well as by working with 5
spaces and padding, as well as creating Subviews with properties that can change. 6
But the most important takeaway from these lessons are going to be how to use SwiftUI to manage the 7
state of the app. 8
In this lesson, we're going to be building out an app that not only has an appearance but it also has 9
functionality. 10
So in this case, the user is actually able to interact with a button on the screen which will be able 11
to change the dice faces in this dice shaker app. 12
Let's get started by creating a brand-new project. 13
And I'm, again, going to choose an iOS Single View App and I'm going to call it Dicer-SwiftUI. 14
Again, make sure that you've got SwiftUI selected as the user interface, and then go ahead and hit Next. 15
Now, save it wherever you like, and then click Create. So the first thing I want you to do is to go ahead 16
and add some image assets to your project. 17
So if you head over to the course resources page, you can find that the Dicee Assets for download under 18
the SwiftUI Module, and then go ahead and download those assets. 19
Once you've got the assets downloaded, unzip the compressed file, and you should find a folder called 20
a Dicee Image Assets. 21
Now, inside here are a bunch of app icons as well as other images that we're going to be using in the 22
app. 23
So I want you to head back over to Xcode in your Assets.xcassets, 24
select the AppIcon placeholder, and click the minus button to delete it. 25
Now, we're going to select all of these app icon sets and image sets, and then just drag it into this 26
section here. 27
And that should add all of the images that we need for this project. 28
So, now we can head back to our ContentView and collapse our left-hand pane. 29
So let's set up the user interface first. In this dice app, 30
I want to give it a background image instead of a background color. 31
So we're going to be using the image set that's called Background that's already in the Assets folder. 32
But go ahead and set up a ZStack with a background image setup. 33
Try and replicate the look that you see here on the right. 34
Pause the video and see if you can complete this challenge. 35
All right. 36
So we can grab a ZStack from our Object library and it's going to be under the first tab, and then I'm 37
just going to drag it into my code. And inside the ZStack, instead of a piece of text, I want to have 38
an image. 39
So I'm going to drag this image view into the stack. And the name of my image, 40
we can just quickly check, it's called background. 41
So let's go back to ContenView and let's change the image name to the string background. 42
So, now once our updates load, 43
you should see that our image background has been placed onto our screen. 44
But the problem is that it's placed in its original aspect ratio which is kind of a square sort of 45
one to one aspect ratio. 46
So in this case, what we need is to make our image resizable. 47
So let's add the resizable modifier, so they can actually change its size. 48
And in addition to making every sizable which makes it take up as much space as it's allowed to, 49
then we're also going to add the ignoring the safe areas, 50
so that was called edgesIgnoringSafeArea. 51
So let's add that as well and make sure that all is applied. 52
So it goes to all four corners ignoring all of the safe areas. And that's the solution to the challenge. 53
Now, let's add the remaining images. 54
So on top of the ZStack, I'm going to create another image view. 55
And in this case, the image view is going to hold the Dicee logo image that came with the assets. 56
So I'm going to create another image and the image was simply called diceeLogo. And there it is. 57
So, now the next objects are not going to go in the Z-axis. 58
It's not going to be on top of the dice logo. 59
In fact, what I need is everything in a vertical stack. 60
So I'm going to hold down my command key and I'm going to drop this diceeLogo into a VStack. 61
Now, in addition to the diceeLogo, I also want to put some of these dice images onto the screen. So I'm 62
going to try and take this dice one image and place it just below my other image. 63
Again, it's going to be using an image component. 64
And in this case, the name was called a dice1. 65
So, now in my preview updates, you should be able to see the logo and the dice face. 66
Now, I'm going to go ahead and resize my dice face. So I'm going to do the same thing as I had up here, 67
so I can either write .resizable. But, of course, following these SwiftUI conventions, it should be 68
lower down so that we can stack each of them together. 69
I'm going to get rid of some of these extra spaces now. 70
Notice how that dice has been stretched beyond recognition. 71
So we're going to change its aspect ratio to make sure that it's always set to an aspect ratio of one 72
which means that it will be one to one on both the vertical and the horizontal. 73
And then I'm going to set the content mode to fit, so that the image actually fitted to the size rather 74
than stretched in an awkward way. Now, because I'm going to need two of these dice faces on the screen, 75
instead of creating another one entirely from scratch, 76
I'm actually going to hold down my commands here and extract this Subview. And I'm going to call my 77
extracted view the DiceView and I'm going to move it just above the content view. And then I'm gonna 78
go ahead and change this number to a dynamic number because we have six dice, and depending on what number 79
I put at the end, I'll end up with a different dice face on screen. So instead of having a hardcode 80
number, I'm going to put a value "n" in there. 81
And when this DiceView struct gets initialized, I'm going to initialize it with the "n" as Int. So, now 82
for this DiceView and it's going to be equal to one, and then I'm gonna drop this DiceView into a horizontal 83
stack and copy it so that I have two of them. 84
So there we go. 85
Now, notice how at the moment, they're going all the way to the edges which is a little bit too much. 86
So I want to add some padding to my HStack. So right at the end of the closing brace for the HStack, 87
I'm gonna hit enter and I'm going to add my padding by writing .padding. And if I go ahead and just 88
add this padding as it is, it will get added to all four sides. 89
But if you only want it on a particular side, then inside the parentheses, you can specify which edge 90
you want to add the padding to. 91
And in my case, I want to keep it just on the horizontal sides. 92
Now, the last element I'm going to add into my user interface is going to be a button. 93
So let's search for a button and just go ahead and drag it into your code. 94
I find that when you actually drag it onto the screen, it has so many options to choose from. 95
You often get it ending up somewhere where you don't want it to be. 96
So I want it inside this VStack alongside my diceeLogo, my DiceViews and my Button. 97
So in this case, the button is going to say "Roll" and the action is going to be determined by what's inside 98
these set of curly braces. 99
So let's hit enter and activate that closure. And let's first modify our Text. 100
So at the moment, it's really, really small. 101
So I want to go ahead and change the font to a system font and I'm going to specify a size. So the size 102
is going to be a 50.font to make it really large. 103
And then I'm going to change the fontWeight to a heavy set font, 104
so just a bit thicker than bold. 105
And finally, I'm going to change the foreground color which is going to be the text color effectively 106
and that's going to be white. And the button itself, 107
so outside of these curly braces, 108
so not in the text area. But down here, we can set the background color of the button to Color.red 109
to make it a red background. 110
And finally, if we want our text to have a little bit of padding before it reaches the edges of the button, 111
we can go ahead and add some padding right here. 112
And, again, if you only want it along the horizontal, then we can use the .horizontal modifier. 113
All right. 114
So now it's looking pretty close to our end results. 115
The only thing that I would, perhaps, change is to just give the image a little bit of padding around 116
four edges, so that they separate out from each other a little bit. 117
So it's easier to see. 118
So in the extracted Subview, our DiceView, I'm going to change the image modifier to add some padding 119
around all four sides. And then let's go ahead and reindent our code. 120
And now that's looking a lot better. 121
So in previous lessons, this is how we've seen all these stacks. 122
Everything is stacked together with a little bit of gap in between each element. 123
But what if we wanted to be able to push the stack to take up the full width or length that it has access 124
to? 125
Well, in this case, we could, for example, add some separation between our dice logo and our HStack. 126
So we would do that using something called a spacer. So a spacer is going to create a flexible amount 127
of space depending on how much space there is on the screen. 128
So if it's a small aspect ratio phone or if it's in landscape, then it would shrink that space down automatically 129
without us having to create any constraints or any order layout rules. 130
So let's go ahead and drag our Spacer in between our image and our HStack which will now push these 131
two away, and the spacer will try to take up as much space as it possibly has access to. 132
Now, in addition to having a space between the logo and the dice, I'm also gonna put a spacer between 133
the dice and my Button, so that everything is pretty much evenly distributed on the screen. 134
That's it. 135
That's all we had to do to set up the user interface. 136
There's nothing really new in the code here that you haven't seen before 137
other than, perhaps, the spacer which is a really flexible component that helps us layout our user interface 138
for different sized screens. 139
So, now all you need to do is figure out how do we change the dice 140
images. And that's exactly what we're going to be covering in the next video where we're going to learn 141
about managing state in the SwiftUI.