All right. 1
So, now that we've completed designing our user interface, we're finally ready to start doing some programming. 2
And we're going to be writing some code to allow us to change some of the properties of those User Interface 3
Elements that we've added earlier on. 4
Now we already know that when we select any of these User Interface Elements, such as these Image Views or 5
the button, we can head over to the Attribute Inspector and change its properties. 6
So, for example, if I wanted this leftmost Image View to show the DiceTwo image rather than the DiceOne 7
image, all I have to do is to select the User Interface Element that I want to change, which is this one 8
right here, and then I can simply type a different image. 9
So, for example, I wanted to show DiceTwo, 10
well, then I would tell it that the image for this Image View should be DiceTwo instead of DiceOne. 11
But if you imagine that our app is already running on a user's iPhone, say, a million miles away because 12
they downloaded it from the App Store, 13
we can then get a copy of their app and change it in Xcode and then send them the new version, right? 14
This doesn't work. 15
So in our Main.storyboard, we're essentially designing all the components that need to be on the screen. 16
And while we're designing it, we're able to change a lot of these properties. 17
But if we need to change these properties on the fly while the app is running, then we're going to have 18
to resort to code. 19
So let's change this back to our DiceOne and let's figure out how we can do exactly the same thing 20
but using only our code. 21
So, firstly, our code file is going to be this one, the ViewController.swift. 22
And when you create any Xcode project, it always comes with some template code for you to get started 23
with. 24
Now, notice how these are actually two completely separate files. 25
The ViewController.swift is our code file and the Main.storyboard is our design file. 26
Now, given that we can only write our code in this ViewController file, how can we access the components 27
in the Main.storyboard file? 28
Well, here's where something called the assistant editor comes in handy. 29
So if you open up the Main.storyboard and head over to the right corner, here you see a number of 30
lines and we can adjust the editor options. 31
So if you click on it, you can go ahead and select the Assistant View. 32
What this means is that we have our design file on the left. 33
So if you take a look up here, you can see that we're inside the Dicee iOS13 project and inside the 34
Main.storyboard file. 35
But on the right here, you can see that it's automatically figured out that the companion code file is 36
the ViewController.swift file. 37
So that's what's showing on the right. In order for us to be able to refer to specific User Interface 38
Elements in our design file, 39
we have to create something that's called a IB outlet or an Interface Builder outlet. 40
So this Main.storyboard is also known as the Interface Builder because we're using it to build the 41
User Interface. 42
And so in order to create our IB outlet, all we have to do is to hold down the control button on our 43
keyboard, not the command button, and then we're going to click on the Image View DiceOne, and then we're 44
gonna drag it over to our code file. 45
Now, make sure that you don't let go until you're ready to drop it. And the place where we want to put 46
it is just below this class ViewController 47
on line 11 and before this override function, viewDidLoad, 48
so anywhere between 11 and 13. 49
And then we're going to let go and we get a pop up asking us what name we should give this connection. 50
Now, this is going to be the name that we'll use in our code file to refer to this specific Image View. 51
I'm going to call it the diceImageView1. 52
Now, notice the way that I've named this. I've started with a word that is completely lowercase 53
and then every subsequent word has the first letter capitalized. 54
Now why do we do this? 55
This is a really easy way of being able to see where each word ends and the next one begins. 56
And you'll see this pretty much commonly across all programming languages not just in Swift. 57
So if we go ahead and click connect, then you'll see that we've created an Interface Builder Outlets. 58
So it's a way for us to be able to access this particular User Interface Element by referring to the 59
name that we gave it which is diceImageView1. Now, this particular way of naming things is called camel 60
casing 61
in programming. 62
Think about a camel and its humps, 63
then you might be able to, with a lot of imagination, see that the first word should be lowercase and 64
every subsequent word is a hump, so it needs to be capitalized. 65
This means that programmers can avoid those situations like those long Twitter hashtags where you can't 66
really tell what it says because all the words are lowercase and you don't know where it starts and 67
where it ends. 68
And similarly, for stationary websites which are called Pen Island, you will have less issues if you were 69
able to keep it camel-cased. Now, coming back to these connections created from the design file to the 70
code file or these Interface Builder connections like this one that we just created, 71
they are a really common source of errors, especially for beginners. 72
So let's say that we've created this IB outlet and at some point, I've decided, you know what, 73
actually, I've made a typo, and now I want to make it read diceImageViewOne, but instead of 1, I want 74
to use the actual word. 75
So now I'm looking at my code and it looks great and there's no errors. But when I actually run my app 76
right now, you'll see that your app will crash. And this is what it looks like. 77
It'll say something like signals SIGABRT and down here, you'll get a whole bunch of stuff being outputted, 78
but if you scroll right to the top, it says, "Terminating app," because of this reason. And the reason is 79
because something is not key value coding-compliant for the key diceImageview1. 80
So looking at this clue, we should be reminded that previously, we had something in here called diceImageView1 81
with that number 82
at the end, but we changed it, right, in the code. 83
Now, what you don't know is that behind the scenes when we create each of these outlets, there's actually 84
code that's being written in the Main.storyboard, and you can view it by right-clicking and opening 85
as Source Code. 86
So we scroll right to the bottom. 87
You can see that one of the connections has a reference to something called a diceImageView1. 88
So that old spelling there. And because we changed it here, it can no longer find it inside this file which 89
is why your app crashes with this particular error code. 90
So I recommend getting really used to seeing this particular type of error when your app crashes and 91
looking at what it is that it has a problem with. 92
So when you do have this issue, then what you want to do is to simply right click and just delete this 93
connection. 94
And now when you run your app, even though this connection is now broken, it won't crash. 95
You can relink it by simply starting from the circle and pointing it back to the element you want 96
to link it to. But in the future, if you actually want to rename one of these outlets or anything else 97
you name for that matter, 98
the best way is to simply right-click on it, and if you're new to Mac that means holding down the control 99
key on your keyboard and clicking on this, and then go to Refactor, Rename. 100
And in this case, it's going to pick up all of the places where this word is used including the 101
Main.storyboard as well as the ViewController.swift. 102
And now if you rename it, it will make the changes everywhere where this name is used. 103
So now when you click rename, then you've done it safely and when you run your app, it won't crash. 104
So just keep in mind this point when you encounter these problems. And remember that when your app crashes, 105
you can always scroll to the very top of the debug area and look at what the reason is. The most useful 106
parts are at the top here. And here, it tells you this particular reason. 107
So when you look at the reason, you can exclude all the parts that are unique to your app, for example, 108
the name of your app and the particular instance, et cetera, and look at the message. So it says something about 109
this class is not key value coding-compliant for this key. 110
Now, this is the same message that it's going to tell everybody that has this problem. 111
So if you go ahead and just copy it and paste it into Google, then you'll find that other people have encountered 112
the same problem, 113
in fact, more than a thousand people, and you'll see people's explanations and solutions for how to solve 114
these problems. Coming back to our code, 115
we've got this line of code that's been written automatically by Xcode when we simply control, dragged 116
and dropped it inside our code file, linking the two files together. 117
When you hover over this little circle, you can see that it's now highlighting the particular element 118
that's actually linked to this particular name. So we can now use this name and change the properties 119
of this particular Image View. And the place where we're going to do it is inside the curly braces of 120
this thing called viewDidLoad. 121
Now, this is what we would call a block of code and it's essentially a bunch of lines of code. Say, currently, 122
it's got two lines of code inside the block and they're all going to be activated depending on a condition. 123
Well, in this case, the condition is when the view loads up, 124
so when your app first shows up on the phone. And what we want to do is we want to change one of the 125
properties of this diceImageView1 when the view loads up. 126
So right now you can see that in our design we've got the first dice image showing up, 127
so DiceOne.png. 128
But I want to be able to show, say, DiceSix as soon as my app loads up. In order to do that, 129
I can use the dot notation. The way that we would write our code is "Who needs to be changed?" Dot. "What 130
property about this thing needs to change?" 131
And finally, after an equal sign, we set the new value, so what it should be changed to. 132
So let's try and apply this. In this case, the "Who" is going to be the diceImageView1. 133
So this one right here. And so we're gonna type diceImageView1. And you can see that as soon as I 134
start typing, Xcode is going to search through all the possibilities and bring the most likely possibilities 135
up to the top. 136
And, indeed, this is exactly the one I wanted to type. 137
So now you can hit either the tab key or the enter key for it to insert automatically. And it's a really 138
good idea to use or to completion with Xcode because it means that you don't make silly mistakes like 139
typos where you have a "V" here or you have an "O" here. And another way to tell if you've made a typo is 140
that when you have an actual piece of code that is recognizable by Xcode, it gets highlighted in a different 141
color 142
once you've finished typing it. 143
In this case, it's the sort of dark sea green. But if you make a typo, say, I had a lowercase "V" instead of 144
uppercase V, it doesn't know what it is, and it will give you an error telling you, "Use of unresolved identifier," 145
which means "I have never seen this thing. 146
I don't know what you're talking about. 147
Check your spelling." 148
So that's another potential downfall that you can avoid by simply using autocomplete. 149
Now, we've got the "Who" we want to change and then we add a dot and we tell it what we want to change 150
about this thing. 151
And in fact, as soon as you write the dot, Xcode actually gives you a whole bunch of things that you 152
can choose from to change, 153
so all the possibilities, but it's a little bit overwhelming. 154
The easier way to do this is to pop up on the Attribute Inspector again and select the element that 155
we want and change, that Image View, and then just simply look at the names of all the properties. 156
So you've got this thing called Image. 157
You've got this thing called Content Mode or Alpha or Background and we can use that name here as well 158
as the "What." 159
So the "Whats" that we want to change in this case is actually that image property. 160
So after the dot, I'm simply going to write image. And you can see that X code also tells me that this 161
is perfectly legal. There is indeed something called image I can change. 162
And down here, it gives you a brief description of what it will do. So by setting this image property, 163
I will change the image displayed in the image view which sounds pretty much exactly like what we want 164
to do, right? 165
And if I scroll around, then you can see that for each of these different properties, it tells me what 166
it will do when I try to change it. 167
But I want to change the image. 168
Now, I've got the "Who I want to change" after the dot. I've got the "What I want to change." 169
And finally, I'm going to add an equal sign and tell it what is the value, what do I want to change it to. 170
So in my case, I want to change it to the dice six image. 171
So this one right here. Now, how can I tell it to change it to that image? 172
Well, there's something really handy called an image literal. 173
And that allows us to define the actual literal image that we want to set as the value of this image 174
view. 175
I'm gonna start typing 176
and I'm gonna write "imageliteral." So all one word and you can see that we've got the image literal being 177
suggested to us. Once that's highlighted, 178
either you can double click on it or you can simply toggle around and hit enter. 179
And now we have a little image that we can select. 180
So if you double click on it, then it pops up with all the possibilities that you can choose from 181
nd I'm going to select the six dice to put in there. 182
So now we've set the who, the what, 183
and finally, the value. 184
And if I run my app right now, once my view loads up, this block of code will trigger and one of the instructions 185
in that block is to change my diceImageView1. 186
This one. It's image property to DiceSix. 187
And you can see that as soon as my app launches, that's exactly what it does. 188
And even though the first dice is shown in our design but, in fact, when our app launches, we see DiceSix 189
because we change it in our code. 190
Now, another important thing to highlight at this point is what we mean by a block of code or when I 191
say write something inside a particular block of code. 192
What does it mean to be inside? 193
So, here we have the same viewDidLoad. 194
And you can see that in between these curly braces, 195
this is where the code will go. 196
So it's a case of when the view loads up, then trigger or the code in between the curly braces. 197
But often you'll have lots of lines of code and it gets a bit confusing 198
if we had to extend it really, really far out this way to keep it all on one line. 199
So often the formatting you'll see in any programming language is something like this where you have 200
the block of code enclosed, again, by curly braces, 201
but the curly braces are now split across multiple lines. 202
But notice that when the brace faces right, 203
that's the opening part, 204
that's the start of the block. 205
And when you see a curly brace facing left, then that's the end of the block of code. And everything in 206
between these two curly braces are the code that will be triggered. And in next code, 207
there's two really helpful tips. 208
One is if you find the closing brace and you just go left and right on it, it will flash to you where 209
the corresponding open brace is. 210
Alternatively, if you double click on the closing brace, it'll actually highlight the entire block. 211
So these are all the lines of code that will be triggered when the view loads up. 212
Now, don't worry too much about some of these other keywords for now like "weak" or "override" or "super." 213
We're going to go through them when we have enough knowledge to understand what they do. But all that 214
we need to know right now is this particular block of code will trigger when the view loads up and we 215
can add as many lines of code as we want into the block in order for the code to happen when the view 216
loads up. 217
So, currently, we're just setting the image of the image view. 218
So here's a challenge. 219
I want you to change the alpha property of this image view. 220
So if we go into the Attribute Inspector after we select this particular image view and I go to the 221
Alpha section, this refers to the transparency. 222
So one means it's completely opaque and zero means it's completely transparent. 223
I want you to set it to point five, 224
so half transparency. 225
How can you do this but not using the Attribute Inspector by using the code? 226
So keeping in mind the Who.What=Value format and keeping in mind what particular property 227
we want to change, try and complete this challenge. if you have managed to successfully complete the challenge, 228
you should be able to see that left-sided image view dim to about half its original opacity, at least 229
compared to the right size 230
as soon as you launch the app. But in the Main.storyboard, you should still see it fully opaque 231
and the Alpha property should still be one. 232
So it's all dependent on your code. 233
Now, I recommend giving these challengers a real good try because these are the moments where you learn, 234
it's not watching tutorials, it's actually giving it a go yourself. 235
But once you're done and if you want to check your solution against mine, then head over to the course 236
links and there will be a link to a solution file on GitHub, and you can scroll through it to see the 237
actual solution and compare it against yours. 238
The next challenge is to set the image of the right-sided dice view by creating an IB Outlet called 239
diceImageView2. Try and think about what you learned in this lesson and change this image to DiceTwo, 240
the second dice image, which is this one, when it loads up, but make sure it still shows DiceOne in 241
your Main.storyboard, 242
and it's only when you run the app does it change that to DiceTwo. And apply what you learn about the 243
Who.What=Value equation and see if you can complete this challenge. 244
And here's the solution. 245
Just as before, we're going to hold down control and click and drag two underneath the previous line 246
and we're going to give this one the same name other than the final number which is 247
diceImageView2. 248
And we're going to click connect. 249
So now we have a reference to that right-sided image view as well as the left. 250
And when our view loads up, we can also tap into the right side, 251
so the diceImageView2 and change its image, 252
and we're going to change it to a another image literal. 253
But this time, we're going to double click and select the DiceTwo image. 254
So now when I run my app, I'm expecting the left one to show the DiceSix, right one to show DiceTwo. 255
And that's exactly what I see. 256
Perfect. 257
While you're learning, it might be helpful to write some comments for your future self in case you take 258
a break and you come back to your code a month later and all of this starts looking like it's a foreign 259
language again, even though right now you know exactly what's going on. The way that programmers do this 260
is through commenting. 261
So we would write two forward slashes and notice how everything I type now will become grade out, 262
so not interpreted as code. 263
And this allows us to leave notes for our future self or for other people who we're collaborating with. 264
So, for example, I might say that an IB Outlets allows me to reference a UI Element, and then maybe downhill, 265
write something like this is the who, 266
and then this is the what, 267
and this is the value. 268
This really depends on you from person to person, 269
people leave different comments. But a well-commented piece of code might make the code look a bit longer, 270
but it does mean that it's easier to understand exactly what's going on without having to spend a lot 271
of brainpower trying to piece it together. 272
Feel free to leave comments to yourself as you go along. But in order to keep the code not overflow, 273
given that I've got such a large font size, I'm actually going to delete these and change all of that 274
back. 275
And we've now learned about changing things in our User Interface programmatically. In the next lesson, 276
we're going to look at how we can detect user interaction and respond to it appropriately. For all of 277
that and more, 278
I'll see you on the next lesson.