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