0 1 00:00:00,360 --> 00:00:07,410 So now that we know more about Swift classes, let's continue building out this class, 1 2 00:00:07,410 --> 00:00:08,780 our SecondViewController. 2 3 00:00:08,820 --> 00:00:15,300 So now that we've got this SecondViewController file that's managing our second screen, we're going 3 4 00:00:15,300 --> 00:00:16,970 to do a few other things. 4 5 00:00:17,010 --> 00:00:23,280 First, I want to show you how we can create the layout and design of our second screen without using 5 6 00:00:23,280 --> 00:00:24,230 the Storyboard, 6 7 00:00:24,240 --> 00:00:29,440 instead we're purely going to be using Swift code to programmatically generate the design. 7 8 00:00:30,390 --> 00:00:37,830 Secondly, I want to initialize our SecondViewController and show it on the screen when the calculate 8 9 00:00:37,830 --> 00:00:39,600 button gets pressed. 9 10 00:00:39,630 --> 00:00:46,530 And finally, we're going to pass over the calculated BMI value that we've got from our first screen over 10 11 00:00:46,530 --> 00:00:51,240 to our second screen, so that it can be displayed. Once you're ready, 11 12 00:00:51,240 --> 00:00:58,950 let's get started. Inside of viewDidLoad is, of course, the code that will be triggered when our view 12 13 00:00:58,980 --> 00:01:00,810 loads up. 13 14 00:01:00,810 --> 00:01:08,590 Now, in our case, what we want to happen as the first thing is to create a new label. 14 15 00:01:08,880 --> 00:01:12,860 Now, whereas previously, we had access to the storyboard. 15 16 00:01:12,960 --> 00:01:19,920 In this case, I'm going to create the label entirely programmatically and it's easy when we can rely 16 17 00:01:20,010 --> 00:01:22,110 on our UIKit. 17 18 00:01:22,140 --> 00:01:30,660 So inside our UIKit, there is a component called a UILabel. And previously, we were able to drag it from 18 19 00:01:30,660 --> 00:01:38,280 the Object library and put this UILabel onto the storyboard, and then link it to an IBOutlet. 19 20 00:01:38,340 --> 00:01:42,570 But at the end of the day, it's still a UILabel. 20 21 00:01:42,570 --> 00:01:51,240 So in this case, we're going to create a new constant code "label" and I'm going to initialize a new 21 22 00:01:51,330 --> 00:01:58,950 UILabel object from the UILabel class. So similar to how we initialize struct, we put the name of the class 22 23 00:01:58,950 --> 00:02:04,180 that we want to initialize, and then we put a set of parentheses. 23 24 00:02:04,200 --> 00:02:09,900 So now we have a label and we can modify some of the properties of our label, 24 25 00:02:09,900 --> 00:02:14,340 so, for example, let's say I wanted to change the text property of our label, 25 26 00:02:14,400 --> 00:02:21,960 I simply just tap into the object that was created to the label, and then write the dot to access the 26 27 00:02:21,960 --> 00:02:28,530 properties and methods, and then I'm going to get hold of the text property, and set it to equal the 27 28 00:02:28,530 --> 00:02:30,090 string "Hello." 28 29 00:02:30,100 --> 00:02:39,240 So now I should have a label that has the word "Hello" as its text. This line of code should be pretty 29 30 00:02:39,240 --> 00:02:40,890 familiar to you by now. 30 31 00:02:40,890 --> 00:02:47,430 It's exactly what we've been doing with our labels created from the object library and referenced with 31 32 00:02:47,640 --> 00:02:48,720 an IBOutlet. 32 33 00:02:49,710 --> 00:02:54,930 And if you're ever confused when you're working with components that come from the Object library, you 33 34 00:02:54,930 --> 00:03:00,400 can always just hold down option and click to see what lies under the hood. 34 35 00:03:00,410 --> 00:03:07,340 So in this case, heightSlider is a UISlider, and our weightLabel is simply a UILabel. 35 36 00:03:07,380 --> 00:03:15,510 However, unlike the UILabel that came from the Object library, that we were able to resize it and move 36 37 00:03:15,510 --> 00:03:17,500 it around and adjust it, 37 38 00:03:17,580 --> 00:03:23,050 well, in this case, we just have a normal label and it currently doesn't actually have a size yet. 38 39 00:03:23,190 --> 00:03:29,180 So to do that, we have to define the frame property. So we write label.frame. 39 40 00:03:29,370 --> 00:03:36,640 And this is the frame rectangle which describes the location and the size of our label. 40 41 00:03:36,960 --> 00:03:46,470 And you can see when you click on it that it expects a CGRect which stands for a cool graphics rectangle. 41 42 00:03:46,770 --> 00:03:53,910 And the way that we would create a CGRect is the same as we would create an object from any class. 42 43 00:03:53,940 --> 00:04:00,730 We write the name of the class CGRect, and then we initialize it with our parentheses. 43 44 00:04:00,930 --> 00:04:07,470 You can see that there's quite a few ways of creating a CGRect or initializing CGRect. 44 45 00:04:07,530 --> 00:04:14,560 But the simplest way is to simply provide an x position, y position, width, and height, all as whole numbers. 45 46 00:04:14,580 --> 00:04:23,010 So that's what I'm gonna choose. And the x position, I'm gonna set as zero, so left, and then y position, also 46 47 00:04:23,010 --> 00:04:23,460 zero. 47 48 00:04:23,460 --> 00:04:25,060 So the very top. 48 49 00:04:25,110 --> 00:04:33,630 So my label is currently gonna go into the top left corner. And then, the width, let's say, 100 points, 49 50 00:04:33,720 --> 00:04:36,090 and the height, maybe 50. 50 51 00:04:36,090 --> 00:04:45,440 So now I should have a rectangle that's at position zero, zero, with a width of 100, and a height of 50. 51 52 00:04:45,690 --> 00:04:54,880 The next thing we have to do is to actually put our label onto the screen. And the screen, 52 53 00:04:54,960 --> 00:05:03,540 in this case, or the very, very basic component that is in every single view controller is this thing 53 54 00:05:03,540 --> 00:05:10,560 called a View, and the view is the very background that comes with any view controller. 54 55 00:05:11,010 --> 00:05:19,200 So if I go into my Object library and I search for a View Controller, and I drag it onto the screen, you 55 56 00:05:19,200 --> 00:05:24,720 can see that it doesn't come with much, but it does always come with a view. 56 57 00:05:25,560 --> 00:05:33,660 So that view is going to be the thing that we want to tap into in order to add our label onto it. 57 58 00:05:33,660 --> 00:05:37,620 So we can't just drag and drop our label onto the screen, 58 59 00:05:37,620 --> 00:05:46,260 we have to tap into this view property, which is the view that this controller manages, which is, again, 59 60 00:05:46,350 --> 00:05:51,360 exactly the same as this thing here in the storyboard. 60 61 00:05:51,360 --> 00:06:01,740 And we're going to use a method code addSubview, addSubview will add a view to a parent view. 61 62 00:06:01,740 --> 00:06:04,620 So this will become the child and this will become the parent. 62 63 00:06:05,070 --> 00:06:12,330 Let's delete the place holder there. And the view that we want to add is our label. 63 64 00:06:12,480 --> 00:06:21,000 Now, notice how our label has a data type of UILabel, but our addSubview needs a UIView. 64 65 00:06:21,000 --> 00:06:24,360 So there seems to be some sort of a mismatch. 65 66 00:06:24,360 --> 00:06:34,190 Why is it possible that we can put this label in even though it's expecting a UIView data type? Well, 66 67 00:06:34,310 --> 00:06:42,970 that's because if we option click on our UILabel, you can see that it inherits directly from the 67 68 00:06:42,980 --> 00:06:43,520 UIView. 68 69 00:06:43,520 --> 00:06:51,680 So this is the parent of the UILabel and the UILabel can do everything that a UIView does and more. 69 70 00:06:51,680 --> 00:06:59,780 So that's why our inputs, our UI Label is, in fact, compatible with the expected data type of a UIView. 70 71 00:06:59,960 --> 00:07:04,430 Because at the end of the day, a label is also a view. 71 72 00:07:04,430 --> 00:07:11,960 Now, the other thing to remember is that when we get a new UIViewController, the view starts out being 72 73 00:07:11,960 --> 00:07:13,130 transparent. 73 74 00:07:13,220 --> 00:07:19,730 So in order to easily differentiate this secondViewController and the view that gets put onto the 74 75 00:07:19,730 --> 00:07:26,480 screen, we should really set its background color. So we can right view.background color, and let's 75 76 00:07:26,480 --> 00:07:34,880 set it to something really obvious like a red color, so we can write UIColor.red, or a much quicker 76 77 00:07:34,880 --> 00:07:42,500 way of doing this is to simply delete that part. And because Xcode knows that the background color needs 77 78 00:07:42,500 --> 00:07:50,870 to be a UIColor, when we simply just write ".red," it already knows that what we want is a UIColor.red. 78 79 00:07:50,930 --> 00:08:01,170 So we can modify our label and our view and customize it all day long, and change all the properties 79 80 00:08:01,170 --> 00:08:09,060 and mess around with it in our code, but currently, there's actually no way of accessing this 80 81 00:08:09,060 --> 00:08:16,320 secondViewController to be able to see our label and our view with the red background color. So we know that the 81 82 00:08:16,320 --> 00:08:19,920 first thing that comes on screen is our view controller. 82 83 00:08:20,400 --> 00:08:28,440 So this is also a good place to make the transition to display our secondViewController and the perfect 83 84 00:08:28,440 --> 00:08:36,180 place is our calculatePressed IBAction, so that when we press the calculate button, we can show the 84 85 00:08:36,180 --> 00:08:39,500 secondViewController. Right here, 85 86 00:08:39,540 --> 00:08:45,480 I'm gonna create a new object from that class that we just created just now. 86 87 00:08:45,480 --> 00:08:49,550 So here is the blueprint for a secondViewController. 87 88 00:08:50,070 --> 00:09:00,240 And here I'm going to create the object called secondVC which is going to be created from the 88 89 00:09:00,330 --> 00:09:02,340 SeondViewController blueprint. 89 90 00:09:02,910 --> 00:09:11,100 And then I'm going to add a set of parentheses to initialize it. And now that I have this object, the 90 91 00:09:11,100 --> 00:09:19,560 secondVC, to be able to actually see it, and to be able to make it display on screen, I have to get 91 92 00:09:19,560 --> 00:09:25,620 the current view controller which is on the screen to present this SecondViewController. 92 93 00:09:25,680 --> 00:09:32,610 So I'm going to tap into the current view controller which can be accessed through the "self" method, which 93 94 00:09:32,670 --> 00:09:38,270 you can see is of type ViewController, which is going to be this class right here. 94 95 00:09:38,850 --> 00:09:40,560 And this is currently on screen. 95 96 00:09:40,590 --> 00:09:50,660 So if it's able to present a ViewController, then I can show my second VC. 96 97 00:09:50,790 --> 00:09:54,250 So I'm going to set it to present animated as true. 97 98 00:09:54,240 --> 00:10:00,790 so I have a little animation when that transition happens. And completion is going to be equal to nil. 98 99 00:10:00,900 --> 00:10:06,260 So once the animation and presentation is done, I don't want it to do anything else. 99 100 00:10:06,270 --> 00:10:08,640 So now if I run my app 100 101 00:10:15,520 --> 00:10:19,270 and I press on my calculate button, 101 102 00:10:19,270 --> 00:10:27,970 well, now I get my second VC, remember with the red background popping up on top, and I've got my label 102 103 00:10:27,970 --> 00:10:35,860 that I've created shown at the 00 position, top left corner of this secondViewController. 103 104 00:10:35,860 --> 00:10:41,070 And we've done all of that entirely with code. 104 105 00:10:41,230 --> 00:10:46,000 Now, we can see our label and our secondViewController, 105 106 00:10:46,540 --> 00:10:54,970 but how can we pass over our BMI value to be displayed on this secondViewController and placed into 106 107 00:10:55,120 --> 00:10:57,550 our label that we created. 107 108 00:10:57,550 --> 00:11:06,740 Well, let's create a property for our secondViewController, let's call it the bmiValue and I'm gonna 108 109 00:11:06,760 --> 00:11:14,370 set it to equals"0.0" to begin with. Next, we're going to use this property, the bmiValue 109 110 00:11:14,760 --> 00:11:16,260 inside our label. 110 111 00:11:16,260 --> 00:11:24,030 So instead of the label text saying "Hello," it's going to display the bmiValue. 111 112 00:11:24,030 --> 00:11:31,980 So now that we have our SecondViewController class with a bmiValue property, we can now pass over 112 113 00:11:32,100 --> 00:11:33,480 our BMI 113 114 00:11:33,480 --> 00:11:36,690 when we create a new SecondViewController object. 114 115 00:11:37,080 --> 00:11:42,580 So here we've initialized a SecondViewController and we can tap into that object, 115 116 00:11:42,600 --> 00:11:51,060 secondVC, accessed that property code bmiValue, and set it equal to the BMI that we've worked out 116 117 00:11:51,300 --> 00:11:52,670 over here. 117 118 00:11:52,680 --> 00:11:59,550 The only problem here is that this bmiValue here is a string, whereas this BMI that we've calculated 118 119 00:11:59,970 --> 00:12:02,180 is a floating point number. 119 120 00:12:02,250 --> 00:12:11,760 So let's go ahead and use our string format method, so we'll use formats, we'll round this down to 120 121 00:12:11,760 --> 00:12:21,420 "%.1f" and then we'll pass in the BMI as the value to be formatted. 121 122 00:12:21,470 --> 00:12:29,540 So now if we run our app and I'm going to delete my print statement now, let's take a look at what happens. 122 123 00:12:33,830 --> 00:12:41,690 Let's go ahead and move our sliders around, and when I click on calculate, you can see the calculated 123 124 00:12:41,690 --> 00:12:49,310 BMI getting placed into the label that we've created entirely from scratch, and it's being populated 124 125 00:12:49,310 --> 00:12:55,520 with the text that comes from that bmiValue property of the SecondViewController. 125 126 00:12:55,520 --> 00:13:04,640 We've now managed to see how we can create our UI entirely with just code without touching the storyboard.