0 1 00:00:00,560 --> 00:00:08,370 All right, so we've got some really really cool functionality inside our Todoey app and we are now fully 1 2 00:00:08,370 --> 00:00:11,850 persisting all of our data using Realm. 2 3 00:00:11,850 --> 00:00:18,330 So, now that we've set up most of the backend and our data storage solution, it's time to think about 3 4 00:00:18,330 --> 00:00:20,200 how we can improve the front-end. 4 5 00:00:20,280 --> 00:00:25,560 And we're going to do just a few things to make our app a little bit easier on the eye because, at the 5 6 00:00:25,560 --> 00:00:30,490 moment, truth be said, it is a very, very lean looking app. 6 7 00:00:30,690 --> 00:00:37,490 And ideally, I kind of need to be able to delete categories if I no longer want them. 7 8 00:00:37,530 --> 00:00:44,010 And at the moment, we don't really have any of that functionality because inside our TableView Delegate 8 9 00:00:44,010 --> 00:00:51,020 Methods, when we tap on any of the rows, we need to take the user to the TodoListViewController, 9 10 00:00:51,030 --> 00:00:52,750 the next view controller, 10 11 00:00:52,800 --> 00:00:57,390 and so we can't really use that to delete the categories. 11 12 00:00:57,390 --> 00:00:59,310 So what else can we do? 12 13 00:00:59,790 --> 00:01:04,650 Well, we can implement something similar to what you see in your mail app. 13 14 00:01:04,740 --> 00:01:11,010 You can reveal the delete button. And if you swipe a little bit further, you can actually automatically 14 15 00:01:11,010 --> 00:01:13,450 delete the contents of that cell. 15 16 00:01:13,470 --> 00:01:16,110 So let's think about how we can implement this. 16 17 00:01:16,140 --> 00:01:21,840 And as always, you will usually find that CocoaPods is going to be your best friend. 17 18 00:01:21,840 --> 00:01:28,440 One of the things I regularly do before I program anything UI or front-end related is to just go window 18 19 00:01:28,440 --> 00:01:31,740 shopping on CocoaPods. So other people like going to the mall, 19 20 00:01:31,770 --> 00:01:34,590 I like going on CocoaPods. 20 21 00:01:34,770 --> 00:01:40,140 So let's go ahead and search for something like "swipe." 21 22 00:01:40,200 --> 00:01:42,500 You can look through each of these libraries. 22 23 00:01:42,540 --> 00:01:48,360 So let's have a look at the first one. You can see that it's got a cute little animation where it shows 23 24 00:01:48,360 --> 00:01:50,750 you what the library is capable of doing. 24 25 00:01:50,910 --> 00:01:56,310 And you can see that this is pretty much a copy of the mail app functionality that we were talking about 25 26 00:01:56,310 --> 00:01:57,490 just now. 26 27 00:01:57,510 --> 00:01:58,810 So this is brilliant. 27 28 00:01:58,810 --> 00:02:02,380 We've found what we wanted in just one search. 28 29 00:02:02,490 --> 00:02:07,530 So let's go over to the get her page and see how we can implement and use this. 29 30 00:02:07,530 --> 00:02:14,220 So they've got a whole bunch of demos in terms of the different transition styles and expansion styles 30 31 00:02:14,280 --> 00:02:15,710 and requirements. 31 32 00:02:15,870 --> 00:02:19,820 And it also shows you how you can install it pretty easily. 32 33 00:02:19,830 --> 00:02:26,180 So all we need is just to pod swipe sell kit so we know all about that. 33 34 00:02:26,190 --> 00:02:28,050 So let's go ahead and implement it. 34 35 00:02:29,040 --> 00:02:31,950 So I'm going to close down my project here. 35 36 00:02:31,980 --> 00:02:33,970 I'm going to open up Terminal. 36 37 00:02:34,260 --> 00:02:37,080 So let's go ahead and cd to it. 37 38 00:02:37,080 --> 00:02:40,310 So the containing folder is currently on my desktop. 38 39 00:02:40,530 --> 00:02:47,520 So I'm going to say cd towards here, and then I'm going to tag on another command, 39 40 00:02:47,520 --> 00:02:54,690 and that's going to be open Podfile -a using the application Xcode and we're not initializing 40 41 00:02:54,690 --> 00:02:58,960 a new pod file because we've already done so in order to use Realm. 41 42 00:02:58,980 --> 00:03:04,290 So if I hit enter, it should find the right directory and open up my pod file. 42 43 00:03:04,290 --> 00:03:09,780 So the part that I'm going to add here is going to be part SwipeCellKit. 43 44 00:03:09,930 --> 00:03:14,070 And if you want to minimize typos, then just go ahead and paste it in. 44 45 00:03:14,100 --> 00:03:21,620 And we're going to hit save and we're going to close this down. And we're going to say pod install, and 45 46 00:03:21,620 --> 00:03:24,270 we'll let that run in the background. 46 47 00:03:24,320 --> 00:03:24,650 All right. 47 48 00:03:24,650 --> 00:03:34,370 So pods are installed. And now we can open up our Xcode workspace and we can work on it using our 48 49 00:03:34,460 --> 00:03:36,070 SwipeCellKit. 49 50 00:03:36,080 --> 00:03:40,010 So let's go ahead and implement it for our CategoryViewController. 50 51 00:03:40,040 --> 00:03:45,560 So before we do anything, we, of course, first have to import the library that we're using which is called 51 52 00:03:45,980 --> 00:03:55,100 SwipeCellKit and Xcode is, again, as always, being a little bit obstructive, 52 53 00:03:55,100 --> 00:03:59,530 but we just need to hit it with a stick by using command B, 53 54 00:03:59,690 --> 00:04:06,410 and that should allow it to figure out where the files for this SwipeCellKit pod exists. 54 55 00:04:06,500 --> 00:04:11,300 Now, even though I've done this a few times, I just want to show you how you might use the documentation 55 56 00:04:11,600 --> 00:04:15,740 of these libraries to learn to use new libraries and new frameworks. 56 57 00:04:15,770 --> 00:04:17,270 And it's really, really simple. 57 58 00:04:17,270 --> 00:04:20,780 So let's scroll down to the Documentation. 58 59 00:04:20,780 --> 00:04:25,720 The first thing that it says is set the delegate property on 59 60 00:04:25,730 --> 00:04:29,840 SwipeTableViewCell, and it's given us a little bit of example code. 60 61 00:04:29,960 --> 00:04:37,170 So I'm just going to copy and paste this over here so that we can refer to it. So let's put this over 61 62 00:04:37,170 --> 00:04:43,750 here and we'll just comment it out in case we mistakenly keep it in there or something. 62 63 00:04:44,220 --> 00:04:49,920 So the first thing that you notice is that they dequeueReusableCell with a particular identifier, 63 64 00:04:50,310 --> 00:04:51,870 and we've got all of that. 64 65 00:04:52,110 --> 00:04:58,110 And it also wants to downcast it as a SwipeTableViewCell. 65 66 00:04:58,110 --> 00:05:02,480 So let's go ahead and do that. 66 67 00:05:02,580 --> 00:05:06,280 A SwipeTableViewCell. 67 68 00:05:06,300 --> 00:05:07,200 There we go. 68 69 00:05:07,200 --> 00:05:12,750 Now, I'm gonna actually collapse my left-hand side, so my text doesn't wrap and you can see it more clearly 69 70 00:05:12,750 --> 00:05:13,550 this way. 70 71 00:05:13,830 --> 00:05:18,510 And then the next thing they have is they set the cell's delegate to self. 71 72 00:05:18,750 --> 00:05:23,800 So let's go ahead and do that as well. And we'll do it down here, 72 73 00:05:24,150 --> 00:05:28,500 cell.delegate = self. 73 74 00:05:28,500 --> 00:05:34,980 So that's the current view controller. And you should be reminded that whenever we're setting delegate 74 75 00:05:35,010 --> 00:05:42,390 on anything, we probably have to move up here and do something with the protocol. 75 76 00:05:42,390 --> 00:05:43,540 So let's read on. 76 77 00:05:43,590 --> 00:05:49,800 And as you can see, it says, "Adopt the SwipeTableViewCellDelegate protocol." 77 78 00:05:49,950 --> 00:05:54,560 So let's copy that and let's go over here and paste it in here. 78 79 00:05:54,570 --> 00:05:57,070 Swipe table view self delegate. 79 80 00:05:57,150 --> 00:06:04,620 Now, as I mentioned before, whenever you find yourself putting in new delegates, then it's usually a good 80 81 00:06:04,620 --> 00:06:07,650 time to put in an extension. 81 82 00:06:07,650 --> 00:06:13,620 So in our CategoryViewController, we don't actually yet have any extensions, so we can go ahead and create 82 83 00:06:13,620 --> 00:06:14,260 a new one. 83 84 00:06:14,280 --> 00:06:20,330 So outside the entire class, we're going to go and create a new extension. 84 85 00:06:20,760 --> 00:06:30,730 So we'll just call it extension and it's going to extend CategoryViewCnontroller. CategoryViewCnontroller. 85 86 00:06:30,810 --> 00:06:36,750 And the reason why we're extending it is because we want to use this SwipeTableViewCellDelegate. 86 87 00:06:36,750 --> 00:06:42,060 So this is going to be the section that we're going to deal with all the Swipe Cell Delegate methods. 87 88 00:06:42,390 --> 00:06:50,670 And just above it then, it's a good point to make a pragma MARK and say this is are SwipeCellDelegateMethods. 88 89 00:06:50,910 --> 00:06:59,800 And you can see, we split up our entire view controller very nicely with these sections and extensions. 89 90 00:06:59,850 --> 00:07:00,160 All right. 90 91 00:07:00,180 --> 00:07:06,120 So the first error we get is that CategoryViewController does not conform to protocol 91 92 00:07:06,120 --> 00:07:06,800 'SwipeTableViewCellDelegate.' 92 93 00:07:07,110 --> 00:07:13,350 So we adopted this protocol in our CategoryViewController, but we actually don't have the delegate 93 94 00:07:13,350 --> 00:07:15,370 methods that are required. 94 95 00:07:15,420 --> 00:07:21,600 So Xcode will add the protocol stubs if you want or why don't we have a look back at the Documentation 95 96 00:07:21,900 --> 00:07:24,110 and see what else is required. 96 97 00:07:24,120 --> 00:07:33,300 So the next function here is a tableView method that allows you to editActionsForRow, and this 97 98 00:07:33,300 --> 00:07:36,920 is something that comes from this SwipeCellKit. 98 99 00:07:36,990 --> 00:07:46,410 So we can simply just copy this entire method and put it inside our extension. And we now have a delegate 99 100 00:07:46,410 --> 00:07:47,110 method, 100 101 00:07:47,280 --> 00:07:52,490 and that error goes away because this was the required delegate method. 101 102 00:07:53,040 --> 00:07:55,710 So what does this code do? 102 103 00:07:56,070 --> 00:08:04,650 Well, it's responsible for handling what should happen when a user actually swipes on the cells. And you 103 104 00:08:04,650 --> 00:08:11,520 can see the first thing is to check and make sure that the orientation of the swipe is from the right. 104 105 00:08:11,520 --> 00:08:19,810 And then we have this closure that handles what should happen when the cell gets swiped. 105 106 00:08:19,830 --> 00:08:25,620 And finally, we add an image to that part of the cell that's going to show when we swipe on the cell, 106 107 00:08:26,040 --> 00:08:31,980 and then we return this delete action as the response to a user swiping on the cell. 107 108 00:08:32,010 --> 00:08:37,400 So we don't actually currently have an image code "delete" inside our Asset.xcassets. 108 109 00:08:37,410 --> 00:08:42,730 We actually have nothing in here so far. But no matter because we can get it straight from 109 110 00:08:42,730 --> 00:08:44,550 SwipeCellKits example app. 110 111 00:08:44,550 --> 00:08:50,550 Now, you can actually download and git close the entire app to have a look at their example, 111 112 00:08:50,550 --> 00:08:55,540 but in my case, I'm just gonna go into the Example folder, and then MailExample. 112 113 00:08:55,540 --> 00:09:01,560 I'm going to go into their Assets.xcassets. I'm going to find the imageset called Trash. 113 114 00:09:02,250 --> 00:09:08,640 And there is something here called Trash Icon.png. And here, I'm going to right-click and I'm going 114 115 00:09:08,640 --> 00:09:11,790 to save image into my Downloads folder. 115 116 00:09:12,060 --> 00:09:18,560 So, now that I've downloaded this thing called TrashIcon, I'm just going to rename it to delete-icon. 116 117 00:09:18,840 --> 00:09:23,730 And that way, it makes a little bit more sense, rather than having the space in the name. And you'll see 117 118 00:09:23,730 --> 00:09:25,190 very soon why. 118 119 00:09:25,230 --> 00:09:31,560 And once you've renamed it, then you can safely drag it into your Assets.xcassets folder in the 119 120 00:09:31,560 --> 00:09:33,180 left-hand pane here. 120 121 00:09:33,180 --> 00:09:38,070 So we're going to put that in there and I'm going to adjust it to the to 2x position because it's actually 121 122 00:09:38,070 --> 00:09:39,650 a 2x image. 122 123 00:09:39,720 --> 00:09:45,360 Now, the next thing I want to do is go back into my CategoryViewController and I'm going to change 123 124 00:09:45,390 --> 00:09:48,420 the name to whatever I called it just now. 124 125 00:09:48,420 --> 00:09:51,780 And just to remind ourselves, it's called delete-icon. 125 126 00:09:51,780 --> 00:09:54,640 So I'm going to delete dash icon. 126 127 00:09:54,660 --> 00:10:01,710 So now what should happen is that when I run my app and I land on the CategoryViewController, when 127 128 00:10:01,710 --> 00:10:12,110 I swipe from the right of the cell, then I should be able to trigger this closure. And inside here, and 128 129 00:10:12,110 --> 00:10:16,360 at this point, I want to print "Item deleted." 129 130 00:10:16,370 --> 00:10:20,660 Now, obviously, nothing's being deleted, but we're just testing our code out here. 130 131 00:10:20,730 --> 00:10:27,950 And when I do swipe, it should show me the "delete-icon" as an image and the "Delete" text underneath that 131 132 00:10:27,950 --> 00:10:29,460 icon. 132 133 00:10:29,520 --> 00:10:35,270 Now, at this point, you might think that you can run your app. But if you do, the Apple actually crash. 133 134 00:10:35,640 --> 00:10:37,290 Let's investigate why that is. 134 135 00:10:37,320 --> 00:10:39,190 What's the reason for the crash? 135 136 00:10:39,420 --> 00:10:44,970 When we run our app, you will get this error and it will crash your app. 136 137 00:10:44,970 --> 00:10:52,830 Now, the reason for this is because it says, could not cast-- It could not turn a UITableViewCell 137 138 00:10:53,040 --> 00:10:56,160 into a SwipeTableViewCell. 138 139 00:10:56,160 --> 00:10:58,680 So how can we fix this issue? 139 140 00:10:58,830 --> 00:11:08,210 Well, let's first stop our app and go into our Main.storyboard, So here, what we can do is we can select 140 141 00:11:08,600 --> 00:11:13,500 our Category Cell and have a look on the right-hand pane. 141 142 00:11:13,670 --> 00:11:22,670 If we go inside the Identity Inspector, we can specify a class that it should inherit from and also a 142 143 00:11:22,670 --> 00:11:25,440 module where that class was located. 143 144 00:11:25,790 --> 00:11:32,340 So here, instead of having it as a UITableViewCell, we can say that it is a 144 145 00:11:32,360 --> 00:11:41,300 SwipeTableViewCell, and hit enter. And then we're going to change the module to SwipeCellKit, and hit save. 145 146 00:11:41,300 --> 00:11:46,280 So let's go ahead and hit run and see if that fixes our problem. 146 147 00:11:46,700 --> 00:11:47,000 All rigiht. 147 148 00:11:47,030 --> 00:11:52,470 So our app no longer crashes, but it looks exactly the same as what we used to have. 148 149 00:11:52,550 --> 00:11:57,200 But now these cells are actually no longer UITableViewCells. 149 150 00:11:57,200 --> 00:12:03,460 They are, in fact, SwipeTableViewCells because that's what we changed its class to. 150 151 00:12:03,500 --> 00:12:15,380 So if we click and swipe to the left, you can see that we've got this trash icon and the Delete message 151 152 00:12:15,380 --> 00:12:16,420 showing. 152 153 00:12:16,420 --> 00:12:21,670 Now, it's a little bit cramped in here because our cell is actually pretty short. 153 154 00:12:21,890 --> 00:12:26,790 So why don't we go back and increase the size of our cell? 154 155 00:12:26,840 --> 00:12:36,670 So let's go into viewDidLoad and let's say tableView.rowHeight equals, let's say, 80.0, 155 156 00:12:36,860 --> 00:12:38,880 so that makes it 80 points high. 156 157 00:12:38,960 --> 00:12:43,050 And let's run our app again and see if we've made it a little bit better. 157 158 00:12:43,100 --> 00:12:49,550 So a lot of UI stuff you'll find yourself tweaking back and forth, running back and forth, just so that 158 159 00:12:49,670 --> 00:12:53,130 you can see visually whether if you're happy with the effect. 159 160 00:12:53,180 --> 00:12:55,460 So, now that looks pretty nice, 160 161 00:12:55,460 --> 00:12:56,130 right? 161 162 00:12:56,180 --> 00:13:02,470 And each of our items get a little bit more space and it doesn't look so bunched up anymore. 162 163 00:13:02,630 --> 00:13:03,320 So, all right, 163 164 00:13:03,320 --> 00:13:04,740 I'm pretty happy with that. 164 165 00:13:04,760 --> 00:13:09,340 So let's test the functionality. When I click on the delete button, 165 166 00:13:09,470 --> 00:13:17,960 I'm expecting this closure to happen and my print line to be executed and, indeed, it does. Every single 166 167 00:13:17,960 --> 00:13:22,470 time I click on the delete button, then it gets deleted. 167 168 00:13:22,470 --> 00:13:27,690 Now, it's no good just printing "Item deleted" into the console, the user can't see that. 168 169 00:13:27,690 --> 00:13:31,880 So let's go ahead and replace this print statement with some real code. 169 170 00:13:32,090 --> 00:13:38,210 And as it suggests, "handle the action by updating our model with deletion." 170 171 00:13:38,210 --> 00:13:46,160 So as a challenge, I'd like you to pause the video and see if you can figure out how to use the indexPath 171 172 00:13:46,160 --> 00:13:48,210 that we get back 172 173 00:13:48,320 --> 00:13:55,910 that's going to tell us which row was swiped upon, and inside here, which row was selected to be deleted 173 174 00:13:56,210 --> 00:14:02,120 when the user taps on that red button, and to use all of that information to delete the correct category 174 175 00:14:02,540 --> 00:14:06,350 from our list of categories here. 175 176 00:14:06,380 --> 00:14:08,660 So pause the video and give that a try 176 177 00:14:11,610 --> 00:14:14,320 All right, so how did that go? 177 178 00:14:14,330 --> 00:14:19,970 Well, as you know, we're going to be adding the code in here because it says that's where we should handle 178 179 00:14:19,970 --> 00:14:20,810 the action. 179 180 00:14:20,870 --> 00:14:27,480 And this is the closure that gets called when the user swipes on the cell and clicks on the delete button. 180 181 00:14:27,500 --> 00:14:34,190 So inside here is where we're going to use our realm.write 181 182 00:14:34,250 --> 00:14:43,430 in order to update our Realm, and the update that we want to make is we want to say realm.delete, and 182 183 00:14:43,430 --> 00:14:52,310 the object we want to delete is the item at indexPath.row, so the row that was swiped on. And we're 183 184 00:14:52,310 --> 00:14:59,240 going to look inside this collection of Results that we've called categories and remove the category 184 185 00:14:59,390 --> 00:15:01,100 at that indexPath. 185 186 00:15:01,100 --> 00:15:08,510 So we're going to say delete(categories[indexPath.row]) 186 187 00:15:08,660 --> 00:15:12,080 Now, of course, realm.write can throw, 187 188 00:15:12,110 --> 00:15:14,270 so we're going to wrap it inside a do 188 189 00:15:14,270 --> 00:15:15,110 catch block. 189 190 00:15:19,940 --> 00:15:23,600 And then we're going to mark realm.write with a try 190 191 00:15:23,620 --> 00:15:24,530 keyword. 191 192 00:15:24,530 --> 00:15:29,180 So the categories here is, if you remember, an optional, 192 193 00:15:29,180 --> 00:15:35,310 so we have to somehow safely deal with it. So we can use optional binding to handle this. 193 194 00:15:35,420 --> 00:15:48,020 So if we say if let categoryForDeletion = categories? two optional chain, indexPath.row, 194 195 00:15:48,080 --> 00:15:59,690 then inside here we can perform the do catch block. And instead of deleting that, we can delete 195 196 00:15:59,900 --> 00:16:02,690 the categoryForDeletion. 196 197 00:16:02,900 --> 00:16:08,600 Now, because some of these are global variables and we're using it inside our closure here, then we have 197 198 00:16:08,600 --> 00:16:15,950 to add self in front of them to explicitly say that they belong to the current class. 198 199 00:16:15,950 --> 00:16:24,110 Now, finally, if all of that succeeded, then we can go ahead and make a call to tableView.reloadData 199 200 00:16:24,110 --> 00:16:32,210 so that we call on data source methods and remove the last cell because it no longer exists 200 201 00:16:32,300 --> 00:16:33,710 in our Realm database. 201 202 00:16:33,770 --> 00:16:38,710 So let's give our app a go and run it to see what happens. 202 203 00:16:38,720 --> 00:16:39,020 All right. 203 204 00:16:39,050 --> 00:16:47,150 So we are going to add a new category, New Category. I'm not feeling very imaginative today. And go ahead 204 205 00:16:47,150 --> 00:16:52,400 and hit Add and we're going to click and drag, and click delete. 205 206 00:16:52,520 --> 00:16:53,340 And there we go. 206 207 00:16:53,360 --> 00:16:59,330 Now, it's gone. All thanks to SwipeCellKit and our little bit of code. 207 208 00:16:59,930 --> 00:17:06,440 So you might have noticed in our current version of the app that it's not quite the same as the mail app, 208 209 00:17:06,440 --> 00:17:13,850 because in the mail app when you click and drag, you can actually drag further and just delete the 209 210 00:17:13,850 --> 00:17:17,850 entire cell by that one swipe gesture. At the moment, 210 211 00:17:17,870 --> 00:17:22,160 you have to do two gestures. You have to swipe and then delete. 211 212 00:17:22,160 --> 00:17:26,300 So how can we implement the same thing that we have inside the mail app? 212 213 00:17:26,300 --> 00:17:31,210 Well, let's head back over to the Documentation and continue reading. 213 214 00:17:31,670 --> 00:17:39,290 So it says that optionally, you can implement the editActionsOptionsForRowAt method. 214 215 00:17:39,290 --> 00:17:46,230 Now, that's a horribly named method, but it does allow us to customize behavior of the swipe actions. 215 216 00:17:46,400 --> 00:17:53,990 And one of the options that we can specify is the expansion style. If we have a look up here at the demos, 216 217 00:17:54,200 --> 00:18:02,660 we can see that the expansion style for destructive is exactly what we want, right? Where if you swipe further 217 218 00:18:02,900 --> 00:18:08,000 than the delete action gets called without you having to tap on any of the other buttons. 218 219 00:18:08,030 --> 00:18:14,230 So let's go ahead and copy this block of code over to our code. 219 220 00:18:14,250 --> 00:18:18,660 We're going to put it below this delegate method here. 220 221 00:18:18,710 --> 00:18:26,050 So right here. Now, there's two options that were specified in the Documentation. 221 222 00:18:26,060 --> 00:18:27,730 One is the expansion style 222 223 00:18:27,770 --> 00:18:29,930 and one is a transition style. 223 224 00:18:29,930 --> 00:18:34,580 So let's have a look at what that border transition style looks like up here. 224 225 00:18:34,580 --> 00:18:40,730 So you can see that in the demo, there's four different transition styles that they show. And border, basically, 225 226 00:18:40,730 --> 00:18:48,950 just allows all the buttons to show up and increase in size at the same time, rather than drag or reveal. 226 227 00:18:48,950 --> 00:18:53,020 So this is not something that we care about too much right now, 227 228 00:18:53,060 --> 00:18:59,720 so I'm actually just going to delete that line of code. And all I'm interested in is this destructive 228 229 00:18:59,750 --> 00:19:00,890 behavior. 229 230 00:19:00,890 --> 00:19:07,460 Now, before we run our app, it's really important to realize this option will try to remove the last row 230 231 00:19:07,490 --> 00:19:08,760 from your table view. 231 232 00:19:08,840 --> 00:19:15,950 So before we can run our app, let's go ahead and delete this reloadData that we added previously. 232 233 00:19:15,950 --> 00:19:20,470 Now, we're ready to go ahead and run our app and see if it works. 233 234 00:19:20,480 --> 00:19:20,740 All right. 234 235 00:19:20,750 --> 00:19:27,470 So let's add a new category, hit Add, and then we're going to click and drag a little bit, and you can see 235 236 00:19:27,470 --> 00:19:33,290 that we've got that delete button show up, and then we're going to click and drag it a lot, and you can 236 237 00:19:33,290 --> 00:19:36,560 see the entire cell simply disappears. 237 238 00:19:36,560 --> 00:19:39,770 And our previous behavior still works, 238 239 00:19:39,770 --> 00:19:43,670 we can still swipe a little bit, and then click delete to remove it as well. 239 240 00:19:43,670 --> 00:19:52,670 And it's got a pretty neat animation when the library removes that row, as you can see when you do this, 240 241 00:19:52,850 --> 00:19:53,340 right? 241 242 00:19:53,360 --> 00:19:54,460 It just shrinks it down. 242 243 00:19:54,470 --> 00:20:03,200 So that is all. Thanks to this destructive expansion style. And all we had to do is put in, what, five or 243 244 00:20:03,200 --> 00:20:05,710 six lines of code for all of that to work. 244 245 00:20:05,720 --> 00:20:07,240 So that's pretty neat, right? 245 246 00:20:07,400 --> 00:20:09,500 Now, what about our 246 247 00:20:09,500 --> 00:20:10,610 TodoListViewController? 247 248 00:20:10,880 --> 00:20:18,590 What if we could have both the behavior of our checking and unchecking, as well as being able to delete 248 249 00:20:18,680 --> 00:20:20,920 item, wouldn't that be neat? 249 250 00:20:20,920 --> 00:20:29,410 So in that case, we would be able to click on the cell to check it and we would be able to click and 250 251 00:20:29,410 --> 00:20:34,990 swipe it to just get rid of it. Because sometimes you want to see the task that you've ticked off and 251 252 00:20:34,990 --> 00:20:39,070 sometimes, you know, you're so done with them that you just want to delete them. 252 253 00:20:39,490 --> 00:20:42,650 So how can we implement that here? 253 254 00:20:42,820 --> 00:20:48,480 Now, you might realize that all that you need is pretty much this extension, right? 254 255 00:20:48,610 --> 00:20:56,170 And you could theoretically copy and paste it over here because it's much the same functionality that 255 256 00:20:56,170 --> 00:20:57,190 we need. 256 257 00:20:57,190 --> 00:21:03,520 But as always when you're copying pasting large blocks of code you should think to yourself, is there 257 258 00:21:03,520 --> 00:21:05,020 a better way of doing this? 258 259 00:21:05,020 --> 00:21:08,220 How can I keep my code more dry. 259 260 00:21:08,350 --> 00:21:16,360 So in the next lesson, we're going to tackle this by creating a superclass that we're going to inherit 260 261 00:21:16,360 --> 00:21:17,040 from. 261 262 00:21:17,050 --> 00:21:20,470 So for all of that and more, I'll see you on the next lesson.