In this lesson, we'll get the grips with UISliders and get them working inside our app. 1
So you should have cloned the starting project and have the project open inside Xcode. 2
Now, first, let's take a look around the starting project. 3
So notice that we've got our Models, View, and Controller folders already created for you. And in our Views 4
folder, 5
we've got our Main.storyboard that has all our designs. But in this case, we've actually got two screens 6
or two view controllers, compared to previously where we've limited ourselves to building single-screen 7
applications. 8
So in this case, we're going to have one screen which is for the calculator where the user toggles their 9
height and weight, and then presses the calculate button. And then, that will take them to the next screen 10
where it shows them their result and some advice. 11
Now, notice that in the calculator view, we've added some UISliders. 12
And if you need to find them they're in exactly the same place that you won't find everything which 13
is, of course, in our object's library. 14
And here we've got a Slider. So it displays a horizontal bar and it represents a range of values. 15
We can define the maximum and the minimum values in the Attribute Inspector 16
once we have the Slider selected. 17
So for my height, which is in meters, I've got the minimum to be 0 meters which, hopefully, nobody is. 18
And I've got the maximum at 3 meters. now, the weight I've set to be zero and 200. 19
So you can feel free to adjust these as you see fit. 20
But I think these will work fine for most people. 21
Notice how we've got these labels here inside a Stack View, and these labels should update to equal the 22
value of the thumb in the Slider track. 23
So I've set the starting value to be 1.5. 24
Now, you can also set it to be at the beginning if you wanted it to be at zero which is the minimum value, 25
but I quite like starting it out in the middle it, looks quite neat. 26
Notice there's also a warning up here that says, "View Controller" is unreachable. 27
And when we click on it, it tells us which one it's referring to which is, of course, this Result View 28
Controller. 29
But don't worry about this warning for now, we're going to fix it when we learn about multi-screen apps 30
and how to navigate to this second screen. 31
For now, we can just safely ignore it. 32
But what we can't ignore right now is our Sliders don't yet work. 33
Now, the behavior that we're after is something like this. 34
We should be able to move the slider along the track and see the Height label here on the right updates. 35
So every time I move the slider, then the associated labels should change its values according to where 36
I am on the slider from the minimum of 10 to the maximum of 200, and the height goes from zero all the 37
way up to three. 38
Now, the height has two decimal places of accuracy, whereas the weight is rounded to the nearest whole 39
number. 40
So that's the objective. 41
That's the behavior we're aiming for by the end of this lesson. 42
But let's break it down into a series of steps. 43
The first step will be printing the value of the slider 44
when we move it along the track. 45
So here's a challenge for you. 46
Can you link up the height slider with an IBAction called height slider changed, and the weight slider 47
with an IBAction called weight slider changed, and then figure out how you can print out the value 48
of each slider 49
when they do in fact get changed. I'll give you a few seconds the pause the video before I show you the 50
solution. 51
All right. 52
So how did you do? 53
Did you give that a go? 54
Well, the first thing that we need to do is, of course, link up some IBActions, right? 55
This is a component that can take user interactions just like the button. 56
How do we do that? 57
We, of course, pull up our assistant view, and then we can start linking up our design with our code. 58
And I'm going to select this horizontal slider which you can see is the height slider and I'm going 59
to control, drag over here, and I'm going to call that action the heightSliderChanged. 60
And notice how the event type that triggers this IBAction is when the value of my slider changes. 61
And to be more accurate and to make life easier for me down the line, I'm going to change the data type to 62
be a more precise data type, rather than any data type. 63
It's going to be a UISlider that's going to be linked to this action. 64
So that's my height slider done and now I'm going to do the same with my weight slider. 65
So this one's going to be called weightSliderChanged. And, again, change the type to UISlider, hit Connect. 66
So now I've got my two IBActions down. Now, the next step is how do I change my code so that whenever 67
this IBAction gets triggered, I can print out the value of my slider where I am on this slider track? 68
So we know that when we select these UISliders in the interface builder, and when we look in the Attribute 69
Inspector, the value property is the one that we actually want, 70
right? 71
Like right now, it's set to 1.5, 72
but I could set it to 1.7, or I could set it to zero, and that moves the little circle along 73
the track. 74
Now, if we go and check in our IBAction, notice how we've got a sender which has a data type of 75
UISlider. 76
So if we tap into the sender which is, of course, that slider, and we wlrite a dot, you can also just scroll 77
through this list and see if there's any properties that you think might be what you want. 78
And we can see that there's actually a property that matches the one we saw in the Attribute Inspector. 79
The value and the explanation is that this will be equal to the slider's current value. 80
Well, that sounds pretty much like exactly what we need. 81
So now all we need is to wrap it inside a print statement, and then copy it over to the weightSlider 82
as well. And you've now got the functionality that we described, 83
so that completes the first two steps. We've linked our Sliders to our View Controller and we've successfully 84
access the value of each Slider. 85
The next thing to notice is that when these values get printed, well, they actually have quite a lot of 86
decimal places. 87
That's a high level of precision. But we don't really need it to be so precise. 88
Here's another challenge for you. 89
Can you figure out how to round the height slider value down to only two decimal places? 90
So we move the high slider, the goal is to only have two decimal places being printed, rather than four 91
or five. 92
So pause the video and see if you can complete this challenge. 93
So there's quite a few ways of doing this. 94
But if I did a just cursory search of how to round a number to two decimal places using Swift, then one 95
of the solutions that you might come across is to use the String formatting. 96
So we pass in the number that we want to be rounded and then we specify the number of decimal places 97
we want by using this "%." and the 2f refers to two decimal places after the floating point, 98
or you could have one 1f for one decimal place, 0f for zero decimal places. 99
So let's try this. In our heightSlider, we already know that we can get access to the sender.value 100
which is going to be quite precise, so it has a lot of decimal places. 101
And this is going to be the thing that we want to round. And if we apply the code that we found here 102
where we write String, and then we type format just like we saw. 103
Well, this particular method is going to return a String initialized by using a given format string as 104
a template into which the remaining argument values are substituted. 105
That sounds pretty confusing but, essentially, all it takes are two inputs: 106
the format string and the thing that you want to format. 107
In this case, the thing that we want to format is, of course, sender.value, so we'll put that in here. 108
And the format string as we saw before, we just had to put "%.2f" just as we have in the 109
code snippet here. And then finally, we're going to go ahead and print this entire string. 110
And now if we run our app, you'll see that functionality I described earlier on, 111
so two decimal places. 112
The next thing to do is our weight slider. 113
We want it to be a whole number. 114
So when we move the weight slider, we don't want to see any decimal places. 115
And so I'm, again, going to leave this as a challenge to you. 116
There's actually multiple ways of doing the same thing. 117
But pause the video and see if you can achieve this effect. 118
All right. 119
So in this case, we could have done what we did before which is where we simply do string format the 120
sender.value, and instead of two decimal places or "2f," we put "0f." 121
And now when we run our app, you can see that we have no decimal places. 122
Now, the alternative way of doing this is we could have also converted our sender.value, which if 123
you check is actually a floating point number, we could actually just convert it into an integer by writing 124
"int," and then having a set of parenthese,s and inside we write sender.value. 125
Now, when I do that, you'll see that I get the same effect again with numbers with no decimal places. 126
So now that we've got our height to two decimal places, I'll wait to no decimal places. 127
We're ready to move on and get the user to be able to see these values. Firstly, we're going to add some 128
IBOutlets. The place that we want to display these values are, of course, this label and this label 129
right here, because the user can't see the debug area, so we need to be able to put these values onto 130
the screen. At the top of my file, 131
I'm going to go ahead and control drag my hype label here and I'm just gonna call it heightLabel and, also, 132
I'm going to create a link from this label right here which I'm going to call 133
weightLabel. 134
Now, I've got my two labels connected. 135
Let's quickly format our code. 136
Well how do I get these numbers into these labels? 137
And I'd like to pose this as a challenge to you. Upon successfully completing the challenge, 138
you should be able to move the slider and see these labels move with you from the maximum to the minimum 139
reflecting the value of the slider. 140
Pause the video and see if you can figure out how to do this 141
Previously, we were already able to print these values to the desired accuracy into the debug console. 142
We now need to get them into these heightLabels and weightLabels. So let's delete the print statement 143
and we're left with the value that we want to put into the heightLabel. 144
So now all we need to do is tap into our heightLabel and then get hold of its 145
text property, and set it equal to the string that we formatted based on the sender.value. 146
Now, if you used this method that I showed earlier where we converted the sender.value into an integer, 147
well it might be a little bit harder to put it into the weightLabel because when we write weightLabel.text 148
equal to Int(sender.value) 149
well, there's gonna be a type mismatch because the right-hand slide is an integer data type, whereas this 150
text property needs a string data type. 151
So how can we fix this? 152
Well, one way is to wrap the integer inside a string. So we first convert this into a whole number and 153
then we convert it into a string. 154
But to be honest, that's quite roundabout, so we might as well just use the same method that we have above 155
which is where we use the format, and then we have "%.0f" for zero decimal places, and then we 156
put in our sender.value. 157
So now if we run our app, you'll see that these labels move when I move the slider. But notice how previously, 158
we had some units in there. But now we move them, 159
the units are gone. 160
Pause the video and see if you can change the code so that when we move the slider, the units stay as 161
they are. 162
So meters for the height and kilograms for the weight. 163
So pause the video and try to do this. 164
All right. 165
So before we start formatting, this line is already getting pretty long. 166
So let's go ahead and set this equal to a separate constant. 167
So I'm going to write "let height" equal this, and then in my heightLabel, I'm gonna set the text property 168
to be equal to an interpolated string. 169
So I'm going to insert the value of my height in here, and then I'm going to tag on the meters unit, and 170
I'm going to do the same with my weight, "let weight" equal that. 171
And then my weightLabel.text is gonna be equal to the weight inserted into my string and then with 172
my kilograms added on at the end. 173
Now, we have this behavior that we want. In the next lesson, we'll use our slider values to calculate the 174
BMI. But to do that, we need to be able to get hold of the slider values outside IBActions. For all 175
of that and more, I'll see you on the next lesson.