Hey, guys. In this lesson, we're going to be looking at more complex layouts and using SwiftUI to create 1
those. 2
In addition, we're going to be using some custom fonts that we're going to download off the Internet 3
and we're also going to be working with RGB colors and HEX codes. 4
Finally, I'm going to show you how to tap into thousands of images that Apple has designed for us to 5
use through SF symbols in SwiftUI. 6
And we're going to be looking at how we can easily extract this Subviews that we've created in SwiftUI 7
to be reused in other projects and other screens. 8
So let's get started. In this lesson, 9
we're going to be extending our SwiftUI knowledge and we're going to be building a really beautiful 10
Stack View enabled personal business card app. 11
So by the end of the lesson, you will have learned how to embed views within other views using SwiftUI 12
as well as a bunch of advance layout techniques to create your business card in a beautiful app that 13
you get your clients to download when they want your details. 14
So get started by creating a new Single View App. And I'm going to call it AngelaCard. But, of course, 15
you can call it whatever you want it to. 16
This is going to be your business card on the App Store. 17
Now, make sure that the user interface is again selected as SwiftUI, and then go ahead and create and 18
save your project. 19
So the first thing I'm going to do is go ahead and create some space for myself. 20
I find that I like to have at least a third of the screen taken up by the preview so that I can see what's 21
going on. All right. 22
So the first step is adding a background color to our app. 23
So here's a challenge for you. 24
Can you remember how to use the Z stack to add a background color and make sure that the color goes 25
beyond the safe areas to cover the entire screen. 26
So if successful, this is what you should end up with. 27
You don't need to change the text element, just the background color. 28
So pause the video and try to complete this challenge. 29
All right. 30
So the first thing that we need to do is to create a Z stack, a stack that allows us to put things one 31
on top of each other all the way from the back of the phone to the front of the phone. 32
So let's go ahead and go into our Object library, drag a Z stack into our code, and then I'm going to 33
replace that text placeholder with the text that we've really got. Now that I've got a Z stack right 34
at the very top of the stack, 35
I'm going to add a color element. And this color is going to be set to green in my case. 36
And in order to make sure that the color goes beyond the safe areas, I'm going to add a modifier which 37
is the one that's the edgesIgnoringSafeAreaModifier, 38
and we want that to go to all four sides. 39
That's it. 40
Now, I recommend formatting these modifiers, so that they actually go below the actual component because 41
you often have quite a few of them. 42
But at the moment, this color looks kind of ugly. And I know that there are quite a few that you can choose 43
from. 44
But what if we wanted a custom color? How would we do that? Now, one of my favorite places for finding 45
a beautiful color palette is a tool called flatuicolors,com. 46
And here, you can see professionally design beautiful colors that are optimized for iOS display. 47
So here, I'm going to choose one of these colors, 48
maybe the green sea color, and I'm going to click copy. 49
This is copied in a HEX code format. 50
So this is a hexadecimal code. 51
And in iOS when we create a color, 52
the easiest way to create a custom color is through specifying the RGB values. 53
And they're expecting a doubles or a decimal place here. 54
And each of these colors, red, green, or blue expects a value between 0 and 1. And 1 would be a full bar 55
of that color and 0 would be none. 56
So for example, if I had a red: 1, green: 0, blue: 0, 57
it would just be the color red. 58
And depending on the mix of these three colors, we can create all sorts of colors. 59
Previously, I've got my copied hexadecimal color code. 60
And if you go to a place called your uicolor.xyz, then you can actually convert your hex color 61
to a UIColor. 62
And it shows you the components that you have to add. 63
So I'm going to go ahead and copy this color right at the bottom, 64
everything inside the parentheses. And then back over here, I'm going to paste it in here. 65
And you'll notice that the SwiftUI way of initializing colors is a little bit different from 66
the UIColor. 67
So the last property, instead of being called Alpha, it's actually called opacity. 68
And in fact, this last component is completely optional. 69
We don't even need to include it. 70
But however, if you wanted to add transparencies, so if you wanted to make it half as opaque, then you 71
could change that property. 72
But in our case, we don't need to, we want it fully opaque. And we have this beautiful green sea color. 73
So I want this piece of text to say my name. 74
So it's a business card after all, they need to know what I'm called. 75
And now I'm going to modify my text. 76
And, again, I'm going to go to my modifiers and I'm going to search for the text related modifiers. 77
So I'm going to go ahead and change the font of my text and I'll change it to a title font, and then 78
maybe I'll make the text bold. And also maybe we can change the foreground color as well. So these are 79
three attributes. 80
It's pretty easy to do. 81
Let's change that to white. 82
So now I have a piece of text that says my name. 83
It's a large title sized font. 84
It's bold and it's white. 85
Now, what if I wanted to be able to add a custom font, so something that isn't already inbuilt to Xcode? 86
Well, a really easy way of doing that is downloading a free for commercial use font from Google, and Google 87
fonts have loads of beautiful typefaces that you can choose from. The one that I have had my eye on is 88
something called Pacifico. 89
So once I found it, I'm going to click plus. And now that I've got this family selected, and I can go ahead 90
and download it. 91
So, now there it is in my Downloads folder, so I can double click on it to unzip and expand. 92
And now I have my actual font file which is the Pacifico-Regular.ttf. 93
So, now I'm going to go into Xcode and popping open the left-hand, pane I'm going to create a new group. 94
So this group is going to be called fonts. 95
And right now, I only have one font, but maybe in the future, maybe I'll have more. 96
So here, I'm going to drag this Pacifico-Regular into my fonts folder, and then making sure that you select 97
Add to targets to be able to use it in this app. 98
So, now we've got Pacifico-Regular loaded into our project, we can go over now to our LaunchScreen.storyboard. 99
So this is our usual Interface Builder storyboard file and I'm just going to add a UILabel in here, 100
just so that I can take a look at the attributes and change the font from system to custom. 101
And then in the family dropdown, I'm going to scroll down just to check and make sure that I've actually 102
got Pacifico loaded and ready. 103
So, now that I've assured myself that I can actually load my custom font, I can now delete it and go back 104
to my ContentView. And here, instead of using the default system font in here, I'm going to load a custom 105
font. And we do that by creating a new font object, and then writing .custom to create a custom fonts. 106
And then we have to give it a name. 107
But it's not enough to simply just write the name of the file, 108
Pacifico-Regular. You can see that if I try to add in the font, custom, and add a size, when 109
you try to preview it, it won't actually change the font size, even though we've seen previously that 110
we've definitely incorporated it into our project. 111
So what's going on? 112
Well, we actually have to change the project settings through our Info.plist file. So remember, these 113
are the property list items where we can specify the settings for our project. 114
So here we have to click on the add button and search for something called Font with a capital "F," 115
we find this one called Fonts provided by application. 116
And this should be an array of items. 117
So in here under item one, you're going to go ahead and add in the name of your new font file, 118
so it's called Pacifico-Regular, and make sure that you add in the font format as well, 119
so it's a .ttf. And then hit enter and check that you haven't made any typos in there. 120
And now, we can go back to our ContentView. And once we refresh our screen, you'll see that it's now able 121
to load up that file and use it in our font for our text. 122
Now, let's continue building out our app. 123
Now, I want to have a bunch of items stacked vertically. 124
So what better than using a VStack. And the VStack is going to be a whole bunch of components. 125
And right now, I've only got one thing that needs to go in the stack which is my Text object. So I'm going 126
to hold down the command key on my keyboard and I'm going to select this Text object. 127
And once I click on it, you can see an extended menu of all the things that we can do to this component. 128
But in my case, I'm just going to embed it in a vertical stack. 129
Now that I've got my vertical stack ready, I'm going to go and add some other components to it. 130
I want to add another text item just below it in the stack. 131
And I find that when I'm dragging and dropping it onto the interface directly, it's actually really fiddly 132
to try and get it to do exactly what I want which is to go just below this current text component. 133
So I find it easier dragging and dropping it straight into my code here like so. 134
This piece of text is going to be my job title. 135
So let's say, it's "iOS Developer." And then we're going to modify this text a little bit. And the modifications 136
I'm going to add is I'm going to change the foreground color of my text to maybe, again. white. 137
And I'm also going to change the font of this text. 138
So let's drag that on as well. 139
And in this case, I'm going to keep the system font, but I'm going to change this to a different font 140
size. 141
So I'm going to select the system with a size of 25. 142
So it's a little bit smaller than the big title, but it should be large enough to be easily visible. 143
Now, on top of my VStack right at the top, I want to add an image of myself, so that they'll be able to 144
know who I am. 145
They'll be able look at the app, look at me, and assure themselves that it's the same person. 146
So I'm going to go ahead and find a image of myself, 147
and here's one that's relatively recent. 148
So let's go ahead and save this image and I'm just going to save it as my name Angela. 149
Now, I can go into my Assets folder and drag that image into my assets and I'm going to make a note of 150
what I've named that file. 151
So it's called Angela. 152
Now in your case, you might have a image of yourself lying somewhere on your computer or on a digital 153
camera, 154
go ahead and drag it in and give it your own name. 155
And once you've done that, we can come back and resume our preview, and then go into our library and find 156
a image object. 157
And I'm going to drag that image right at the top of my VStack like so. 158
So the image name, well, at least my image name was called Angela. 159
Yours might be called something else. 160
But once we've done that, it should load in the image at its original size. So it might be too large or 161
it might be too small. 162
So how can we resize it? 163
Well, we have to first make it resizable. 164
So that's one of the modifiers. 165
And if we search for it, we should be able to find image resizable which is what I'm going to drop onto 166
my image component. 167
And then you can see that it's going to stretch to fill all the available space now, which is not what 168
I want, 169
and I definitely don't want to be stretched to look like a stick. 170
So instead, I'm going to go and find something called aspect ratio. 171
So this is going to allow me to define the aspect ratio of the image and the content mode. 172
So instead of trying to fill all the available space, I'm going to change it to fit which will keep the 173
aspect ratio of the original image while it's being resized. 174
Now, at the moment, it's still a little bit too big. 175
So I'm going to change its size by searching for the frame modifier, and then I'm going to drop it onto 176
my image, and I want my image to be, maybe, have a width of 150 and a height of 150. 177
So that way it should be large enough to see, but not large enough to see the imperfections. 178
Now that I've created my image, I don't really like how it's a square. 179
So how can I turn it into a circle? 180
Well, there is a modifier. 181
You've guessed, called a Clip Shape. 182
And this allows us to clip the shape using a particular shape. 183
And if you remember, if we go back to our components here, we've got loads of shapes down here: ellipse, 184
circle, rectangle, rounded rectangle, a whole bunch of things. 185
So let's see how we would do this. In order to clip our current image, 186
we have to add this clip shape as a modifier to the image. And by default, it's set as a circle. 187
Now, once it reloads, you can see my image has now turned into a circular profile photo. Pretty easy, right? 188
Now, 189
what if in addition to the circle, I wanted a little border around my profile image. 190
What can I do to achieve that? 191
Well, I could use something called Overlay and this layers a second view on top of the existing view. 192
So that means our image is going to be behind and our overlay is going to go on top, and we get to put 193
something in the overlay. 194
In my case, it's just going to be drawing a circle. 195
Let's go ahead and add our overlay to our image. 196
And at the moment, the overlay is trying to overlay some text. But what I actually wanted to overlay is 197
a circle object. And instead of just a normal circle which is going to obscure my face, I'm going to change 198
the circle into a stroke. So that instead of being a filled shape, it becomes a line shape. And the content 199
of the stroke is going to be a color, 200
so I'm going to say Color.white, and the line width is going to be a floating-point number which I'll 201
set to maybe 5. 202
So, now you can see there's a picture of me inside a white border which is laid on top of my image. 203
Pretty neat, right? 204
And so far, so very easy. 205
Now, the next thing I'm going to do is I want to add some contact details, so that when people have downloaded 206
the app,. they can get in touch with me through email or through phone. 207
So let's separate out this section which is kind of about me from the section which is going to be my 208
contact details. And to do that, I'm going to use a divider component. So if you scroll down here, there's 209
a whole bunch of shapes and there's this one called a divider. 210
I'm going to add that right at the bottom of my VStack. 211
And once it reloads, you'll be able to see it's now separated out my content into top and bottom areas. 212
So below my divider, I'm going to create another shape. 213
So I'm going to set this to you as a challenge. 214
This is the effect that I'm going for. 215
It's a rounded rectangle shape. 216
And on top of the shape, I've got a overlaid text component. 217
See if you can achieve this effect using what you've already learned. So, pause the video and compare against 218
this template to complete the challenge. 219
All right. 220
So, I already gave you a clue that I'm going to use a rounded rectangle. 221
So around a rectangle is simply a rectangle with a corner radius. 222
So if we go ahead and drag that down, maybe just below the divider in our code, you can see that it creates 223
this gigantic rounded rectangle which is trying to fill up all the available space in the VStack. 224
The first thing we need to do is to make it a little bit smaller. 225
So I'm going to add a modifier which, remember, is the frame modifier that changes the size. 226
And I'm going to drag it down and put it in here. 227
In this case, it's got a width and a height, but actually both of these properties are optional. 228
So I can if I want to just let the width be set by the parent. 229
So it's going to try and fill as much space as it has access to and only defined the height. 230
So in my case, the height is roughly around 50. 231
Don't worry if you've got 40 or 60 as long as it looks just about right, then it's fine. 232
Now that I've got a frame, I can see that my rounded rectangle is a little bit less on the round and 233
a little bit more on the rect side. 234
So let's change the corner radius to a little bit higher. Instead of 20 people, we can make it 25. 235
And this way it looks a lot more like the image that I showed you. 236
So the next thing we have to do is change it to a white color. 237
And the easiest way of doing this is to set the foreground color to white. 238
And notice how with everything, text or shapes, you can always set the foreground color as long as it's 239
something that is a vector image. 240
So not something that is JPG or PNG, you can always set its foreground color. So I said that on top 241
of this rounded rectangle, we were going to add an overlaid text. 242
So let's go ahead and search for overlay and drag and drop this onto our rounded rectangle and we're going 243
to add a text component. And our text component is going to be the phone number that we're going to show 244
people. 245
So let's add a phone number, 246
123 456 789. 247
That's it. 248
Done. 249
There's our phone number. 250
But we can't see it. 251
What's going on? 252
Well, we have to change the color of the text. 253
You can see that when I click on this text component it's actually getting highlighted in the preview. 254
But at the moment, it's actually set to be the same as the foreground color. 255
So it's white which is why we can't see it, white on white. 256
Let's go ahead and change its color, so its foreground color to black, so that we can actually see it 257
up here. And in fact, a much better way of setting shape colors rather than foreground color is to use 258
something called fill. 259
So we can fill our rounded rectangle with some content. 260
And in my case, this content is simply just going to be a color. 261
So we're filling that shape with a white color. 262
And now you can see that even if our text didn't have a foreground color, it would be automatically set 263
as black. 264
So both ways work. 265
This involves a little bit more reading from the documentation. 266
But as long as you've managed to achieve this look, then consider yourself successful. 267
So what if we wanted to add a little icon on the left here to signal that this is actually a phone number 268
and not just my favorite number or something like that? 269
Well in order to add that image of the phone icon, I'm going to use the SF Symbols that we talked about 270
earlier on in the course. 271
And if you remember, we downloaded the SF Symbols app which allows us to browse through all of the 272
thousand or so images that we can choose from. 273
And in my case, I'm going to search for an image of a phone 274
and I'm going to choose the phone.fill 275
to use in my app. Now, down here at the very end, I'm going to create an image. And instead of 276
creating it like we have done up here where we've just given the name of the image as it appears in 277
the Assets folder, I'm going to choose a different initializer. 278
I'm going to choose the one that takes a system name. And that system name refers to the name that we 279
saw over here from the SF Symbols. 280
So I'm gonna put phone.fill. And once it updates, you can see that there's that little icon right 281
there, the little phone icon. 282
So here's a challenge for you. 283
See if you can use that image that we created just now from the SF Symbols to add it into our little 284
rounded rectangle here. 285
The goal that you're looking to achieve is something like this with the phone image in green right next 286
to our phone number, 287
all nested inside this rounded rectangle. 288
So pause the video and see if you can complete this challenge 289
All right. 290
So the first part is easy. 291
If we wanted to change the color of our image, all we have to do is add a foreground color modifier to 292
it, 293
and I'm going to change it to green to match the background. 294
Now, the next part is how do we get our image and our text to be horizontally aligned. 295
Well, it sounds like the job for an HStack, 296
right? 297
So, in SwiftUI, we can't actually select multiple items yet and try to embed them both into a stack, 298
instead you have to select one. 299
So in this case, it's going to be the text in the overlay 300
and I'm going to put it into an HStack, and then I can move my image to the front of the HStack. 301
Remember that the HStacks go from left to right and the VStacks go from top to bottom. 302
So if you want something right at the top, then keep it at the top of the stack. 303
And if you want something right at the left, keep it at the top of the HStack. 304
So, now I've got my phone and my phone number inside my rounded rectangle. 305
The only thing to change is that maybe it would be nice to have a bit of padding so that my rounded 306
rectangle is not all the way touching the edges. 307
Now, in web development or web design, we would normally probably just add a margin to this rounded rectangle 308
or we might add some padding to theHStack. 309
But the way that we do it in US development is we actually add the padding to the component that needs 310
to be padded away. 311
So if you come from web design, then you'll think of it as the margin to add the padding. 312
I'm going to find my padding in my modifiers, and then I'm just going to add it right at the end. 313
And I'm going to add a padding to all four sides, top, left, right, and bottom. That's starting to look pretty 314
nice. 315
But if I wanted to create another one of these, I don't want to have to retype all of this code and have 316
all of this repeated code. 317
So how can I extract this rounded rectangle so that I can reuse it? 318
Well, I can hold down my command key and select my rounded rectangle which contains pretty much all the 319
components that are reusable. 320
And then I'm going to click on extract subview. And you can see here's my extracted view that it's taken 321
out of my code and you can see that Xcode is refracted it and is asking me the name for both of them. 322
So I'm gonna call this the InfoView because it's gonna display my email and my telephone number. 323
And to make this reusable, I have to change the icon that's going in it and the text that's going inside. 324
Now, you might even want to have a custom color or a custom fill color for the rounded rectangle, the custom 325
height. 326
But in my case, I'm going to keep it simple. I want my InfoViews to pretty much all look the same, but 327
I do want to change the text that goes in. 328
So this is going to be a string, and also the image name. So this is also going to be a string. 329
And then I'm going to replace this systemName with imageName and I'm going to replace the text with the text 330
property right here. 331
So, now I can initialize a new image view just below the divider and add in some values for those two 332
inputs. 333
So the text is going to be my phone number and the image view is again going to be phone.fill. 334
So, now once it updates it should look exactly the same as before because I haven't changed anything 335
other than refactor out this InfoView which I can now reuse in a lot of places. In order to keep our 336
code neat, often you'll find that we would create a new file which will create as a new SwiftUI View, 337
and we'll call this view the InfoView. And inside this InfoView, 338
I'm going to delete the default struct that gets created. And instead, I'm going to cut and paste in this 339
InfoView that I created just now. 340
So, now when you actually take a look at it in terms of the preview, you can pass in some parameters for 341
its initializer. 342
So text and imageName. So let's initialize 343
here our text and imageName. 344
Text, I'm just gonna put "Hello" and the imageName, 345
phone.fill again. And this data is just used to create the preview here. 346
So let's click Try Again and let it try to render this InfoView. You can see that we can now just see 347
the InfoView. And because this is just a single component, it doesn't really make sense to preview it 348
in an entire phone, 349
right? 350
It looks a bit lonely there. So we can instead use a modifier on the preview by calling previewLayout 351
and the value to pass in is sizeThatFits. 352
So this is going to render our preview to fit the size of our component. 353
So, now we can actually see it in all its glory and instead of being rendered inside a phone bezel. 354
So, now that we've separated out our InfoView, we can go back to our ContentView and create our second 355
InfoView. 356
So right below the phone number one, I'm gonna create another one which is going to hold my email. 357
So the text in this case is going to be my email, angela@email.com. And my image name for this 358
email one is going to come from SF Symbols. 359
So let's search for mail and see what we get. 360
This envelope.fill looks pretty good, so let's use that. So envelope.fill. Cool. 361
So there it is. 362
We've now managed to develop a fully designed business card app using all sorts of advanced layout modifiers, 363
as well as seeing how we can extract views for repeated use and to preview the components in their own 364
unique sizes. 365
So I hope you had fun with this project. And in the next module, I'm going to show you how to build a 366
app that actually has functionality in addition to appearance. 367
So for all of that and more, I'll see you there.