All right. 1
So you should have downloaded and unzipped or git cloned 2
the calendar project to your desktop, and we're going to go ahead and open it up inside Xcode. 3
So first things first, I just want to show you around the Main.storyboard that I've created here. 4
Now, you'll notice that the design looks a little bit different from the one that we ended up with at 5
the end of the Auto Layout module. 6
And that's because I added a few more modifications just to make it look a little bit more realistic 7
and more similar to the version of calculator that we've got on the Mac. 8
So a couple of changes that I made are, firstly, I've reduced the space between all of the items inside our StackView. 9
So when you click on any of these StackViews, you can see that the spacing is only one point between all 10
of these gaps. 11
I've also made the background view black so that these gaps show up as lines outlining each button for 12
us. 13
And I've also split up the bottom part by placing these two items in their own stack view, and then stacking 14
that along with the 0 into another vertical stack, so now it distributes equally. 15
And I've also changed the font to a thin font at 50 points and some of these other ones a little bit 16
bigger as well, a system 30, for example. 17
So now that we've taken a look at the design part, it's useful to take a look at what these parts are 18
all linked to. 19
So I've already created IBOutlets and IBActions. 20
So the only outlet that we've got, currently, is the one that's linked to the displayLabel which is this 21
one up here, and this displayLabel is going to be the one that's going to show up our results of our 22
calculations, as well as the numbers that the user types into the keypad. 23
Now, there's two IBActions. 24
One of these IBActions are linked to all of the calculation buttons and it's called calcButtonPressed. 25
And the other one is linked up to all of the number or the digit-related buttons, 26
and it's called numButtonPressed. 27
And we're going to be using these two methods in order to implement the functionality of our calculator, 28
but it's important that you realize which buttons are linked to which method. 29
So just familiarize yourself with that. 30
So once you're ready, we can crack on and start building our calculator. 31
So first things first, we want the user to be able to tap on any of these numbers and have it show up 32
up here in the displayLabel. 33
So as I mentioned before, the numButtonPressed is the action that's responsible to a tap on any of 34
these buttons. 35
So this is what should happen when a number is entered into the keypad. 36
And this is also where we're going to add our code. 37
So previously, in the Xylophone app, if you remember, we also had multiple buttons linked up to the same 38
IBAction, and in that case, what we did was we gave each of these buttons a different Tag value. 39
And by looking at what the Tag value of the sender was, we figured out which button was tapped on. 40
Now, that's a little bit manual, and it involves you having to edit the tags manually one by one which 41
is a bit of a pain. 42
So as I always say, programmers are lazy, so what can we do that makes it a little bit easier and less 43
manual? 44
So I want to know the identity of the button that was tapped. 45
And I know that that information is stored inside this object called sender. 46
Now, the sender has a whole bunch of different properties, such as what is the background color, 47
well, in this case, it's blue, or what is the size of the button, for example. 48
Now, you can also see that these different buttons already have a title, right? 49
They already have some text in them. 50
And if I could just figure out what the text was of the button that triggered the IBAction, then that will 51
be really helpful for me to implement my calculator functionality. 52
So if we tap into the sender object and we use the dot to find all of its properties, even if you just 53
start searching randomly for what you think could be the name of the property, Xcode is very helpful 54
in pulling up all of the related properties and methods. 55
So in my case, I kind of want to know what the title of that button is. 56
So I might say sender.title and you can see that it's giving me a whole bunch of suggestions. 57
Do I want the titleLabel? Do I want the title for UIControl.State? 58
And you can see which ones are variables, which ones are methods. Or do I want the titleColor, titleRect? 59
Now, you can see that there's two contenders in this case. 60
One is the tie to a label, and this as it describes down here, is a view that displays the value of the 61
current title property for a button. 62
So we could go through it this way. 63
But there's actually even better one if you scroll through this list. 64
There's this one called current title and the description for this one is the current title that's displayed 65
on the button. 66
Well, that's perfect, right? 67
That's exactly what we need in order to figure out which button was pressed. 68
Now, there's a lot of documentation that you can look up online and you'll find all the help in the world 69
on Stack Overflow and Google and blog posts 70
but there's nothing that is quite as quick and easy as just searching for what you want and just coming 71
up with a name that you think is likely, and then scrolling through that list for a good contender, 72
just as we did here. So in my case, I want to set the display label's text to the current title of the button, 73
so that means if the user taps 1, I want this to read 1. 74
Now, I can do that by tapping into my IBOutlet displayLabel, and then going into its text property and 75
setting that equal to sender.current title. 76
Now, there's just one problem. 77
If you hold down alt and click on current title, you can see that this is a String question mark, 78
so this is an optional string. 79
And if we read through the discussion, the last sentence says that the value may be nil. 80
Well, what if we had a button that didn't actually have a title? 81
Well, in that case, sender.currentTitle will be nil 82
and this line of code will crash your app. 83
Now, another neat thing that you can see now that you know all about computed properties is that you 84
can see that this currenTitle property is a get-only property, 85
so it's read-only. 86
So that means we can't, for example, say, sender.currentTitle equals something, something, that doesn't 87
work because as it suggests currentTitle is the currentTitle that's in the button, and it doesn't let 88
you to give it a new value by setting it. 89
And this is achieved through making currentTitle a computed property that only has a get defined and 90
no set. 91
So here's a little bit of a practical example of what we've been learning about in the last module. 92
Now, in our case, I don't really want this line to crash. 93
So what I want to do is I'm going to use a "if let" and I'm going to call it a numValue, 94
so the number value. 95
And I'm going to set that to equal the sender.currentTitle. 96
And if this sender.currentTitle happens to be not nil, 97
then inside the "if let" is where we're going to set the displayLabel.text to equal to that new 98
unwrapped numValue. And you can see now numValue is just a bog-standard regular string as 99
opposed to an optional string. 100
So we can test our app and see what we get. 101
All right, so here's our simulator on the left here, 102
and I'm going to tap on the 7 and you can see 7 shows up in here. 103
Now, this is just a bit of an issue with our app and I'm sure you can already see it. 104
Now, what if I wanted two digits? 105
Well, I can't at the moment. I can only put in one digit because I'm setting the displayLabel.text 106
to equal whatever button was pressed through these three lines of code. 107
So here's a challenge. 108
Can you figure out a way of appending the numbers that the user keeps on tapping on, so that inside the 109
displayLabel, we display the entire number that they wanted to put in? 110
So for example, if I wanted to type 150, I should be able to see 150 show up up here. 111
And to only set it back to nil or allow a new number to be entered 112
when I click on any of these other buttons. 113
So this is pretty much classic calculator functionality. 114
You don't need me to go through it any more than that. 115
So pause the video and see if you can complete that challenge. 116
All right. 117
So, basically, what we need to do is to append each of these numValues to each other and display it 118
in the displayLabel until the user taps on one of these calculate buttons. 119
So a typical case would be, say, for example, I'm trying to type in 150 plus 3, 120
right? 121
So when I type plus, then I can clear the 150, and I can start from scratch on the 3. 122
So in order to do that, I need to have some sort of property that keeps hold of whether if the user is 123
done typing the number. 124
So let's go up here, and just below IBOutlet, 125
let's create a new variable and let's call it isFinishedTypingNumber. 126
This is a little bit wordy but, hey, we've got Xcode autosuggesting everything, so we don't have to type 127
everything out, 128
so why not make it super clear. 129
So isFinishedTypingNumber is going to be a Boolean and it's going to start off in life as being true. 130
So when we first start up our app, then isFinishedTypingNumber is going to be true. 131
So, now we can go inside our numButtonPressed and we can check to see if isFinishedTypingNumber 132
is equal to true. 133
You can either use this full syntax where you have it checking with a double equals or you can simply 134
just delete that and everything between the "if" keyword and the open curly brace is evaluated. 135
And if it is true, then this block will be carried out, 136
otherwise, it will not. 137
So inside here if isFinishedTypingNumber is true, then that means we're just starting out, 138
and the number in the label is probably 0 or we're just starting out with a new number that we want 139
to type. 140
So in that case, we do want to set the displayLabel.text to equal the numValue, so the value 141
of the button that got pressed. 142
So when I first start out the app, the display label says 0 and isFinishedTypingNumber is going 143
to be initialized to true. 144
So in this case, when I press one of the buttons, then that is the value that is going to go into this 145
UILabel. 146
Now, once we've set a number into the label, 147
so the first number is showing up in there, 148
then we have to switch this isfinishedTypingNumber to false, because we are not done typing the number, 149
right? We've just typed in the first number, and until I press one of these buttons, the orange or the 150
gray buttons, I want my calculator to accumulate all the numbers, so that I can type a number that is 151
more than one digit. 152
For example, I want to be able to type 150. 153
So inside here, we can define our else case. 154
So namely, when this IBAction is triggered and we are not finished typing number, we've just started typing 155
a number, 156
then we should be able to accumulate the number by appending them to the previous number. 157
So in this case, then we can say displayLabel.text is equal to the current text in the displayLabel, 158
plus, or rather append what is currently the numValue. 159
So what this line of code will do is it will look at the currentTitle of the button that was pressed 160
and it will append that value to what is currently inside the displayLabel here. 161
So if I run this code now, you can see that when I type 1, 162
now at this point isFinishedTypingNumber is set to false. 163
So we're going to go inside this else bracket, and that means that the next button I press will get 164
added or appended to the previous value of the displayLabel, 165
and now I have 15. And if I keep going until 0, I can keep adding numbers and it will continue to append. 166
Now, ideally, when I press any of these buttons, for example, plus, I want to be able to start typing a new 167
number, instead of continuing to append numbers. 168
So in order for that to happen, we have to go into our calcButtonPressed because, remember, this 169
IBAction is linked to all of the calculation buttons. 170
And here I'm going to set that variable isFinishedTypingNumber to 171
true. 172
Because if I've typed a whole bunch of numbers, and then I press the add button, then I'm pretty much finished 173
typing number, right? 174
I want to type a new number to add to my last number. 175
So, now let's run our app with that minor update. Now, you can see I can type 150, 176
and then when I press any of these buttons, say, plus, then I can add in a new number, 150 plus 250. 177
Now, none of the equal signs or anything else works because we haven't implemented anything in there. 178
But you can see I've already managed to use our variable isFinishedTypingNumber and toggling it state 179
to be able to make my calculator accumulate numbers when I need it to, and to forget about the numbers 180
when I need it to as well.