0 1 00:00:00,300 --> 00:00:07,050 In the last lesson, we got the grips with the UITableView and figured out how we can populate it with 1 2 00:00:07,110 --> 00:00:10,110 message items from our message model. 2 3 00:00:10,140 --> 00:00:17,460 Now, in this lesson, we're going to improve the design of our table view a little bit by using some custom 3 4 00:00:17,490 --> 00:00:23,460 cells, instead of these bog-standard UI table view cells that comes preloaded. 4 5 00:00:23,460 --> 00:00:29,660 So the first thing we're gonna do is I'm going to go into the Views folder and it's here that I'm going 5 6 00:00:29,660 --> 00:00:32,100 to create my new files. 6 7 00:00:32,160 --> 00:00:37,050 So right click on the Views folder and create a new file. 7 8 00:00:37,290 --> 00:00:46,890 And this is going to be a Cocoa Touch Class from iOS and it's going to be a subclass of a UITableViewCell 8 9 00:00:46,980 --> 00:00:49,380 like this. 9 10 00:00:49,920 --> 00:00:56,150 And it's gonna be called a MessageCell with a capital "M" and a capital "C." 10 11 00:00:56,370 --> 00:01:03,720 And remember to tick this box to create a design file which is called a XIB file that's gonna be associated 11 12 00:01:04,110 --> 00:01:06,480 with this class of MessageCell. 12 13 00:01:06,660 --> 00:01:12,480 Make sure the language is Swift, and then go ahead and click Next. In the next screen, 13 14 00:01:12,480 --> 00:01:18,270 make sure that it's going to be added to the Views folder in here under Group and that the Target: Flash Chat 14 15 00:01:18,270 --> 00:01:22,200 is checked, and then click Create. 15 16 00:01:22,440 --> 00:01:25,040 Now, it's going to create two files for us, 16 17 00:01:25,080 --> 00:01:31,260 the MessageCell.swift which is this file right here, and something called a MessageCell.xib. 17 18 00:01:31,710 --> 00:01:37,990 So the XIB is a design file which is going to be used by our MessageCell. 18 19 00:01:38,040 --> 00:01:44,130 So when it says awakeFromNib, the Nib is an old name for the XIB. 19 20 00:01:44,160 --> 00:01:49,740 So, essentially, what's happening here is it's going to initialize whatever it is that we put into this 20 21 00:01:49,740 --> 00:01:51,500 design right here. 21 22 00:01:51,540 --> 00:01:53,410 Let's go ahead and design it. 22 23 00:01:53,430 --> 00:02:02,340 The first thing I'm going to add is a UIView onto the screen and I'm going to resize this view so that 23 24 00:02:02,370 --> 00:02:09,780 it pretty much just fits along the left, and I'm going to change its background to one of the custom 24 25 00:02:09,780 --> 00:02:15,390 colors that are from our Assets folder that you should already have preloaded, 25 26 00:02:15,390 --> 00:02:20,840 and we've called them the BrandBlue color, BrandLightBlue, LightPurple, and Purple. 26 27 00:02:20,940 --> 00:02:28,320 So I'm going to change the background here to the BrandPurple. And inside this UIView, 27 28 00:02:28,350 --> 00:02:35,330 I'm gonna add a label. This label is gonna go inside this view. 28 29 00:02:35,450 --> 00:02:40,820 Next, I'm going to head back into my Object library and look for an Image View to put onto the right 29 30 00:02:40,820 --> 00:02:41,670 side of the cell, 30 31 00:02:42,230 --> 00:02:45,290 and this is going to show my avatar image. 31 32 00:02:45,290 --> 00:02:52,880 Once it's in place, we're going to go ahead and drop our view and our Image View into a Stack View. 32 33 00:02:52,960 --> 00:02:57,990 And because they're stacked horizontally, immediately, we get a horizontal stack. 33 34 00:02:58,010 --> 00:03:04,050 So, now I'm going to select my Image View and I want to give it some width and height constraints, 34 35 00:03:04,160 --> 00:03:08,970 so I want the width to be 40 and I want the height to be 40 as well. 35 36 00:03:09,050 --> 00:03:12,570 And then let's go ahead and hit enter to add those. 36 37 00:03:12,710 --> 00:03:21,440 The next thing to do is I'm going to select my Stack View and I'm going to add constraints, 10 from every 37 38 00:03:21,440 --> 00:03:22,630 single edge. 38 39 00:03:22,670 --> 00:03:27,620 And when you click the dropdown, it should be relative to the content view which is going to be the size 39 40 00:03:27,650 --> 00:03:28,880 of the cell. 40 41 00:03:28,880 --> 00:03:34,190 So once you've added all of those and turn them red, then go ahead and add those four constraints. 41 42 00:03:34,190 --> 00:03:41,300 The very final thing we have to do is to define some constraints for the label inside our view. 42 43 00:03:41,420 --> 00:03:48,020 And in this case, it's also going to be 10 points away from the edge of that purple view. 43 44 00:03:48,530 --> 00:03:51,040 So let's go ahead and add those four constraints. 44 45 00:03:51,470 --> 00:03:58,250 And now you'll see that all of our errors and warnings have disappeared, but our view is a little bit 45 46 00:03:58,250 --> 00:04:04,520 off the screen, so we can resize our cell just to make it fit the actual content. 46 47 00:04:04,580 --> 00:04:09,710 And now that we've got our constraints in place, we can leave it like this. 47 48 00:04:09,770 --> 00:04:17,000 The final thing I want to change is to select the Stack View and change the spacing between the items 48 49 00:04:17,060 --> 00:04:23,240 from 8 to 20 to give a little bit more space between the image view and the label. 49 50 00:04:23,240 --> 00:04:29,740 And finally, I'm going to change that image view to have the MeAvatar image inside. 50 51 00:04:29,870 --> 00:04:32,750 So it's starting to look a bit like a message bubble 51 52 00:04:32,750 --> 00:04:39,830 now, right? Now, just as what we've done with our Main Storyboard, the view control is in it, and the Swift 52 53 00:04:39,830 --> 00:04:44,190 files, we can also do the same thing in our MessageCell.xib. 53 54 00:04:44,210 --> 00:04:52,520 We can go over here and show the assistant editor. And because our message cell here is linked to our 54 55 00:04:52,520 --> 00:04:58,420 Message Cell Class, then this is the file that's automatically going to show up from the right. 55 56 00:04:58,430 --> 00:05:04,370 So what we want to do is to create some IBOutlets, so that we can actually tap into them and change 56 57 00:05:04,370 --> 00:05:05,540 their properties. 57 58 00:05:05,630 --> 00:05:10,360 So the first IBOutlet I'm going to create is one from the view here. 58 59 00:05:10,790 --> 00:05:17,600 So I'm going to control drag that over here and I'm going to call it messageBubble, and then hit connect. 59 60 00:05:18,230 --> 00:05:20,890 The next one is the actual label. 60 61 00:05:20,900 --> 00:05:26,300 So it's a little bit small on here and you might end up sort of clicking on the wrong thing when you 61 62 00:05:26,300 --> 00:05:27,540 create the outlets. 62 63 00:05:27,560 --> 00:05:31,580 I think it's easier to control click on the document outline elements here. 63 64 00:05:32,180 --> 00:05:38,390 So from our label, we're going to drop it down over here to a separate line, and I'm going to call this 64 65 00:05:38,420 --> 00:05:41,960 outlet just label, and then hit connect. 65 66 00:05:42,440 --> 00:05:44,270 So, now we've got two outlets. 66 67 00:05:44,270 --> 00:05:50,510 And the final one I'm going to add is going to come from this image view right here, the meAvatar image 67 68 00:05:50,510 --> 00:05:51,070 view. 68 69 00:05:51,260 --> 00:05:56,390 So I'm going to call that rightImageView, and then hit enter. 69 70 00:05:56,390 --> 00:06:04,760 So, now we've connected up those elements to our message cell and we're ready to go ahead and use this 70 71 00:06:04,760 --> 00:06:12,050 Message Cell class as the UITableView which will display in the table view of our ChatViewController. 71 72 00:06:13,470 --> 00:06:21,930 The first step of using a custom designed file, a custom xib file, is to register it in the viewDidLoad. 72 73 00:06:21,930 --> 00:06:24,990 So in our ChartViewController's viewDidLoad, 73 74 00:06:24,990 --> 00:06:29,630 I'm going to go ahead and register that NIB with my tableView, 74 75 00:06:29,790 --> 00:06:35,260 so I'm going to say tableView.register. 75 76 00:06:35,690 --> 00:06:43,080 And in this case, we're going to choose this one to register a NIB forCellReuseIdentifier. 76 77 00:06:43,310 --> 00:06:50,960 Let's go ahead and hit enter. And the NIB in this case that we have to create is going to be a UINib 77 78 00:06:52,410 --> 00:06:56,080 and it's going to be initialized using the nibName. 78 79 00:06:56,280 --> 00:06:59,820 So the nibName is the name of this file, 79 80 00:06:59,850 --> 00:07:06,530 so it's the part before the .xib part, so it's capital "M," capital "C," MessageCell. 80 81 00:07:06,690 --> 00:07:13,560 But because we've already created a Constants file where I've created this type property called 81 82 00:07:13,560 --> 00:07:21,170 cellNibName and set it equal to "MessageCell" as long as your XIB file is spelt exactly the same as here, 82 83 00:07:21,180 --> 00:07:22,890 MessageCell.xib, 83 84 00:07:23,040 --> 00:07:28,970 And if not, you can change it right here to make sure that this matches this string right here. 84 85 00:07:29,280 --> 00:07:33,750 And now we can use this cellNibName inside here. 85 86 00:07:33,750 --> 00:07:42,530 So we'll say K.cellNibName and the Bundle is gonna be set as nil, and the CellReuseIdentifier, 86 87 00:07:42,660 --> 00:07:46,890 remember in our constants, we've got it as "ReusableCell," 87 88 00:07:46,890 --> 00:07:51,130 so I'm going to copy this string right here, go back into my XIB, 88 89 00:07:51,180 --> 00:07:58,770 select that cell Message Cell, and then go into the Attributes Inspector and put it right here as the 89 90 00:07:58,770 --> 00:08:01,700 reuse identifier. So hit enter 90 91 00:08:01,740 --> 00:08:04,830 and that should be activated now. 91 92 00:08:04,900 --> 00:08:10,750 Now, we can, again, use that Constant K.cellIdentifier in here. 92 93 00:08:10,750 --> 00:08:17,530 So, now that we've registered our table view, the next step is to go down here into our table view data 93 94 00:08:17,530 --> 00:08:21,080 source method where we're creating our cell. 94 95 00:08:21,110 --> 00:08:27,640 Now, notice how previously, we were just decueueing a bog-standard UITableView cell. 95 96 00:08:27,640 --> 00:08:34,690 Now, in this case, in order for us to know about all of those properties in that particular class the 96 97 00:08:34,690 --> 00:08:47,120 Message Cell class, we have to use the "as!" keyword to cast this reusable cell as a Message Cell class. 97 98 00:08:47,140 --> 00:08:54,730 And it's only after we do that can we actually write cell.label which is that IBOutlet that we created 98 99 00:08:54,730 --> 00:09:03,260 just now, .text, and set it to equal the message body from our messages array. And now we can actually 99 100 00:09:03,260 --> 00:09:10,460 go into our Main.storyboard and actually delete this prototype cell or ReusableCell because we're 100 101 00:09:10,460 --> 00:09:12,940 no longer using it anymore. 101 102 00:09:12,980 --> 00:09:19,490 Instead, we're using the cell that's created from the MessageCell.xib with our custom designs and 102 103 00:09:19,490 --> 00:09:22,170 our custom IBOutlets here. 103 104 00:09:22,460 --> 00:09:23,420 Let's try this out. 104 105 00:09:23,450 --> 00:09:31,490 Let's go ahead and run our app and see if we're able to show this design in each of the cells 105 106 00:09:31,490 --> 00:09:31,760 in our table view. 106 107 00:09:36,740 --> 00:09:38,540 And you can see, there we go, 107 108 00:09:38,540 --> 00:09:43,550 we've got our message showing up and we've got our avatars showing up on the right. 108 109 00:09:44,030 --> 00:09:48,280 So it's still looking a little bit ugly, but at least it works, right? 109 110 00:09:48,470 --> 00:09:54,290 And it's able to populate the label right here with the text that we got from our messages array. 110 111 00:09:55,010 --> 00:09:58,460 Let's make this look a little bit better, shall we? 111 112 00:09:58,460 --> 00:10:01,710 Let's go ahead and change some of these things. 112 113 00:10:01,730 --> 00:10:05,620 The first thing I want to change is the label text color. 113 114 00:10:05,810 --> 00:10:10,690 Instead of having it as the default, I want to change it to the BrandLightPurple, 114 115 00:10:10,820 --> 00:10:18,110 so they contrast nicely with the background. And then I want to make this background, this Message Bubble 115 116 00:10:18,110 --> 00:10:23,910 UIView to have some rounded corners to make it look a bit more like a message bubble, 116 117 00:10:23,960 --> 00:10:24,830 right? 117 118 00:10:24,860 --> 00:10:26,350 So how do we do that? 118 119 00:10:26,360 --> 00:10:33,230 Well, if we go into our MessageCell.swift and locate the awakeFromNib method, 119 120 00:10:33,230 --> 00:10:39,620 this is one of the methods that's really similar to the sort of the viewDidLoad in a view controller. 120 121 00:10:39,620 --> 00:10:46,430 This is going to be called when we create a new message cell from the MessageCell.xib. 121 122 00:10:46,430 --> 00:10:54,560 So it's right here. When our app is running that we're going to set the messageBubble's 122 123 00:10:55,740 --> 00:11:04,200 layer.cornerRadius property, and instead of setting it to equal a constant which means it's always gonna 123 124 00:11:04,230 --> 00:11:06,550 be that particular roundness, 124 125 00:11:06,720 --> 00:11:12,780 instead, I'm gonna make it a little bit more dynamic. So I'm gonna to happen to the messageBubble's frame 125 126 00:11:13,320 --> 00:11:21,870 and size, and then I'm going to take its height. Because, remember, as our messages grow if they get longer, 126 127 00:11:21,900 --> 00:11:25,650 then this message bubble is gonna get taller and taller. 127 128 00:11:26,070 --> 00:11:30,270 So I want my corner radius to adapt with that height. 128 129 00:11:30,270 --> 00:11:35,670 So my corner radius is gonna be equal to the height divided by 5. 129 130 00:11:36,030 --> 00:11:45,940 And now let's run our app and log in, and you can see we've now got some message bubbles. 130 131 00:11:46,250 --> 00:11:52,230 So feel free to adjust the corner radius fractions as you please. 131 132 00:11:52,250 --> 00:11:58,520 You can make it even rounder by increasing the size or less rounded and more square by decreasing that 132 133 00:11:58,520 --> 00:11:59,290 value. 133 134 00:11:59,570 --> 00:12:06,090 But, essentially, we've now got some very bubbly looking cells. The very last thing that you should be 134 135 00:12:06,090 --> 00:12:11,780 aware of is that, by default, labels only get to have one line. 135 136 00:12:11,790 --> 00:12:17,970 So that means if you have lots of text in your message, I certainly know a lot of people who like sending 136 137 00:12:17,970 --> 00:12:20,370 me long messages, 137 138 00:12:20,370 --> 00:12:22,230 then notice what happens. 138 139 00:12:22,230 --> 00:12:25,190 It actually gets cut off and truncated here. 139 140 00:12:25,240 --> 00:12:30,440 So all we have to do is change the label's lines property to zero. 140 141 00:12:30,990 --> 00:12:39,690 And what that does is it allows that label to expand and in turn makes the UIView behind it grow 141 142 00:12:39,690 --> 00:12:40,770 well. 142 143 00:12:40,860 --> 00:12:45,640 And when it grows like this, it looks kind of weird when the avatars kind of in the middle. 143 144 00:12:45,810 --> 00:12:52,230 So we can also select the Stack View and make the alignment to the top, so that this is the person who 144 145 00:12:52,230 --> 00:12:56,100 sent the message and their message will extend this way. 145 146 00:12:56,100 --> 00:13:01,650 So let's give that a run and see what that looks like. Cool. So that's it. 146 147 00:13:01,650 --> 00:13:03,650 We've got our message bubbles set up. 147 148 00:13:03,780 --> 00:13:10,710 We've got our avatar image and we're using these custom xib files as well as custom components in order 148 149 00:13:10,710 --> 00:13:12,750 to fill up our table view. 149 150 00:13:12,780 --> 00:13:20,510 So in the next lesson, we're going to be sending some actual messages to our Firebase Cloud Firestore. 150 151 00:13:20,520 --> 00:13:24,330 So that's all to come and I'll see you on the next lesson.