Advanced Table View in Swift 5 (Xcode 11, 2020) - iOS Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Applause] welcome back to another swift video in today's video we're going to be looking at how to set up a little bit more of an advanced table view so what we're going to set up is what you see here we have our awesome header here with a video that plays we have this horizontally scrolling component which is just a collection view and then we can also pass in a list style for a section with these normal cells like the ones you traditionally see in like the settings app and such and we're going to talk about not only how to set this up and build it but how to really separate out our views our models our controllers and how to dynamically set up how many rows we want to show up in the collection view so we don't have to hard code stuff and kind of all the nitty gritty if you will uh and i think the video part kind of brings us to life too so i i threw this in as a nice little uh ad so we're gonna be looking at how to put this together that said make sure you absolutely destroy that like button down below for the youtube algorithm helps out quite a bit helps me make more videos for all of you hit subscribe while you're at it if you haven't subscribed already get xcode ready get excited and let's jump right in quick pause before we get into the video if you haven't seen it already i am hard at work putting together ios academy.io a community where all of us ios engineers can come together learn how to build some of the top apps like facebook youtube and instagram in addition to interview prep to land some of these ios roles at top tech companies so if you're interested in the free and premium content to come head on over to ios academy dot io and enter your email address in the waitlist form and you will be notified as content becomes available that said let's get into the video get started by creating a new xcode project we'll stick with a single view app and i'm going to call this my table view go ahead and save it on your desktop and let's jump right in so the very first thing i'm going to do here is bring in these images that i grabbed from google images so head on over to your xc assets and i think we have seven car images so i'm going to create seven image sets in here and we're just going to call it car suffixed by the number so let's create those really fast and then we'll get into the nitty gritty of setting up our awesome looking table view as well as customizing it and setting up headers and all that good stuff so i think that's it we've got one two three four five six seven so let's uh select it and drag in our images what images you use are irrelevant for the video i just grabbed them from google images go ahead and grab whatever image you want or you can get them from an api call if you have your app set up that way let's bring this one in and two more and this one and i also went ahead and grabbed a video here and we're going to use this in our table view header so drag that in as well i just downloaded it from youtube i think it's like a ferrari commercial or some car related video so drag that in let's expand our xcode window and start writing our code so we're going to want to set up the table view in our controller and we're also going to want some custom cells so i'm going to create a folder here and i'm just going to call it cells and we're going to want two custom cells one is going to be a subclass of a ui table view cell and this one is going to nest a collection view so i like to call it collection table view cell and go go ahead and hit enter twice to create and save it and we're also going to want to create a custom collection view cell which is going to be used in said collection view so i'm going to call this table collection view cell go ahead and create it and save it like so and let's uh let's set up the basics of our controller and we'll come back to those cells so the first thing we're going to want to do in here is create a table and it'll be a table view we're going to create a table in this format with this anonymous closure we're gonna want a frame of zero and we're gonna use the grouped style we're gonna return said table we want the constructor call there we're gonna also want to register um cells so we're going to have as you saw in the beginning of the video a cell that has a collection view as well as a standard ui table view cell so let's just implement the standard one so it's the one that's built in so we're going to register that now we're going to want to add this as a sub view like so we're going to want to set its delegate and its data source up and what else we also want to set a frame to this guy and viewed it a layout sub subview so go ahead and override that function and assign it to view.bounds we're going to want to create an extension off of this controller and implement the table view delegate as well as the table view data source whoops like that and the functions that we want are as follows we're going to see a number of sections we'll just hard code these until we set up our model uh number of sections is one number of rows will also return one we're also going to want cell for row at index path and we're going to say this is a dequeued cell with an identifier of cell which is the one we registered for and pass in the index path in here we're just going to say cell dot text label dot text we'll just say hello world and we're going to return the cell we also want did select row add index path and this gets called obviously once someone selects the row at the index path we're going to call deselect to unhighlight it and the last function we want in here is height for row at index path and we're going to return 50 for now so i just set that up super quickly so if you're not familiar with basic table views i encourage you to take a look at my other videos on it i have a bunch of table view videos so let's go ahead and just hit command r to build and run make sure our basic table view is showing up in our simulator so there's our simulator there is our app let me also go ahead and change this to dark mode so we're going to go to settings and appearance and turn on the switch here for dark mode i just like developing in dark mode personally and we have our table view here we have this cell tapping it of course nothing happens so let's let's basically create our collection view table view let's set up all that code and then our models so we have a table view subclass here let's go ahead and start with this guy so we're going to want to start by deleting all of this crap that it gives us and we're going to want to create a collection view this is going to get set up in our initializer so go ahead and just define it and you want to override the constructor that looks like this with a style and a reuse identifier you're going to want to call the super on it and before this we're going to want to set up set collection view as a ui collection view with a frame and a layout the frame we're going gonna pass it is gonna be dot zero and layout will be layout so we can create the layout right here it'll be a ui collection view oops ui collection view flow layout on the layout we're going to save the scroll directions horizontal we're also going to provide an item size for each of these cells in this collection view with a width and a height and we're going to say 170 by 170. this will be important and we're going to come back to this at some point in this video and we're also going to provide section insets and these are going to be ui edge insets with a top uh left bottom and right and we're gonna say three three three and three and let's see so after we've set this up we want to add it as a sub view so we're gonna say content view of this cell add sub view collection view we're also going to say shows horizontal scroll indicator to false and same for the vertical it just doesn't look very nice to show those indicators so we'll do that and then we also want to uh so this is giving us an error because if we override the initializer we also need to bring in this required decoder one so hit that error and hit fix and it'll put it there for you we also want to set up the delegate for the collection view and the data source and we also want to register a cell similar to what we did for the table view so ignore these errors for a second we're not conforming so it's going to yell at us but we have this custom collection view that we're going to set up in a second but go ahead and come in here and just add a static identifier so we can register the cell in that table view so add that in here come back to the table view and now you can say i want to register this class with this class dot identifier and let's conform to all of these the delegate and data source on this table view subclass so those errors go away so you want to add an extension to this guy and you want a ui collection view delegate ui collection view data source and you also want a ui collection view delegate flow layout this guy let me also go ahead and close my inspector here since we're not using it and let's add our curly braces and let's go ahead and implement all of these and let me also add a line break here so we're going to put the functions in here and we'll just hard code some values for now obviously we need to be passing in some models and we're going to set that up after we have most of this code in place so we're going to say number of sections this one's going to be 1. number of rows is going to be whoops it's going to also be one that's not what we want we know we want number of rows number number of the number of items that's what we want number of items we're also going to want to sell for item cell for item this is going to be collection view we're going to dq the item similar to what we do for our table view and what we're going to dq is this kind of cell that we registered so we're going to say the item identifier is the cell name dot identifier for index path which is that we're going to do a as exclamation mark so we can cast it and we can return the cell and let's see what else do we want we also want did select item at index path and similar to the collection view we want to start by deselecting it like so so let's actually talk about how the models are going to get plumbed through to this table view cell and then subsequently set up the collection view cell so the first thing we want to do before we plumb stuff through is set up the models so our collection view is going to show a cell with a title and an image and our normal table view cell which just shows like a normal cell with a label is just going to show a label like the one we have here so i'm going to create another file in here and i'm going to call it models it'll be a swift file and let's talk about the three types of things that we want in here the first thing that we want is going to be an enum and this is going to be a cell model and this is what we're going to use in our table view on the view controller to figure out what type of cell we want to show it's going to have two cases first one's going to be a collection view and next one's going to be a list now both of these are going to take associated parameters themselves an associated type of models which is going to be a collection of the specific model for that type so for the list case we are going to create a list cell model which is simply going to have a title in it we could just use a string but it's always good practice to use a concrete model and we're going to put that there and now we're going to have a collection table cell model this one's going to have a title and a image name and this one is going to go into the case for this guy and the other thing we're going to do is we're also going to have a parameter for the collection view uh case in here for rows and this is going to determine how many rows in our uh collection view in the table of view how many rows we're going to show there it's a little bit tough to explain but once you guys start seeing it it'll make more sense and this is going to take an integer so now what we can say is if we go back to our view controller whoops that's not what we want we want our view controller we can come in here and say there is a property called models which is going to be a collection of cell models and i'm going to set up a or call a function here called set up models let's go ahead and create that function and we're just going to append to our data what did i call it models so we're going to say models dot append and we're going to basically append if you just put a dot either a list or a collection view so we'll start with a collection view and the next thing it wants is an array of this collection cell model thing collection table cell model and number of rows we'll say is two to start let's open up this guy and we're gonna pass in collection cell models collection table cell models this one and if you open this up it wants a title and an image name so i'm just gonna say car one car one and we can just copy and paste this a couple times so let me put enter there we put a line break there as well ctrl i this to align it properly and let's go ahead and copy and paste these seven times and control i to fix the indentation let me copy and paste these so that's two three four five six seven ctrl i should fix up your indentation get rid of the last comma hit command b make sure things are compiling we added quite a bit of code and always good practice to hit command b periodically to build go ahead and change these now that i think about it i could have used a for loop to set this up but oh well we copy and pasted it hopefully you guys got the point that's five six six seven and seven whoops seven and we appended this one we also want to append one of those list models so we're going to do another append that we're going to say a list and the list takes a list cell model array so open up that array and create a list cell model which i think is just a title and we'll just say first thing and it's copying paste a few times change these up kind of irrelevant what's in the string and yeah so this is how our models are set up on the controller and now in the table view functions we're going to set these up even further because we have this models collection now so if we scroll down for number of sections we are going to return models.count for number of rows we're going to return model the section that we're at dot uh rather we're gonna return let's see so what we're gonna do just kidding we're gonna actually switch on this thing because this thing is an enum and the cases are we have a list which has a model's array itself as an associated value and we're going to return the number of models that it nests and similarly we have the collection view as well and this is going to also have models and rows but we don't really care about the rows we can do underscore and we're going to return once again models.count and you can return or get rid of that last value and for the cell itself what we're going to do is we're going to put a switch in there too so let me copy this and put this here and once again instead of returning the count we're going to actually want to return a cell now so in the case of a normal list we're going to want to basically return this guy the current model and the position that we want is going to be in a model index path dot row section is going to be index path dot section now this model has a title so we can say this is model dot title and in this guy's case we're going to want to return that collection table cell thing that we were creating but first we want to register it to our table view so here we just registered a basic table view cell go ahead and copy and paste that and you also want to register a i think we call the collection whatever we call a collection table view cell that's not what we want collection table cell model no what did we call it this guy collection table view cell that autocomplete isn't deciding to show up so we want to register that for uh that class dot identifier but something is off because it's not working so let's do a command b i don't think i copy and pasted it right and copy that again there we go now it's syntax highlighting let's try that one more time collection table cell table view cell what i could have saw i called it that let's go back one more time and copy and paste it yeah collection table view cell and it is a ui table of view cell so we're going to register this dot self there it is okay to this dot identifier did we add an identifier let's double check come back here yeah we added a we made a private though oh no we didn't even add one so let's go ahead and add a static identifier to this guy and i like to call it the same thing as the class and then now here you can say this dot identifier and this is why i like to create the identifier just so you don't have to use strings like we did here make sure it helps you make sure that you don't misspell something and it breaks everything so now that it's registered there we can actually use it in that cell for row function so it's complaining here that we're not using this model so we're going to get the actual model out of this by once again saying model actually we don't even need to get the model out of it what we're going to do is we're going to say let's sell equals table view we're going to want to dequeue for this identifier at this index path as this kind of cell and we're going to return said cell now what you might be wondering is where are we passing in the models and that's a great question we're going to go into our table view subclass and we're going to do two things in here first thing that we're going to do is add a property for the models that the collection view is going to use so this is going to be collection cell models this thing collection view cell models make sure it's var so you can mutate it and you're going to want to add a public function called configure configure with models it'll be a collection of those models we're going to say self.models equals models and you're going to say collection view reload data so now we can go back to that table view and here we can say cell dot configure with and pass in those models like so and let's come back to this table view subclass and we also want to give the collection view a frame that i just realized we didn't do so we're going to say we're going to override layout sub views call super layout sub views and we're going to say collection view dot frame is the entirety of the content view so we're going to say content view dot bounds so go ahead and hit command b and everything should be working in terms of compiling we need to update the collection view functions now because we have this models property on the cell now so number of sections will still be 1 but the number of items will be models.count and in this case we want to configure our collection view cell with the given model at the position so we're going to say model equals models index path dot row and let's not worry about the did select for a second now we're going to command click into the collection view subcell or subclass and we didn't do anything in here but the first thing we'll do is we're going to set up a function like we did on the table view it'll be public and we're going to say configure with model and it'll just be a single instance model for this cell so it'll be collection view cell model and our collection view like i said is going to have an image and a label so let's go ahead and create those two properties we're going to say my label is a label and let's go ahead and put those back there [Music] let's create that label in here like so and we're going to set up the labels properties as well so we're going to say label text alignment will be centered and let's just leave it like that for now let's return the label we also want an image view so we're going to say my image view image view image view and let's also call this image view so it's named appropriately like that and this func in this function right here with the configure we can say label or my label dot text going to be model and model now has a title and an image name so model.title and the image view you can probably guess we're going to assign the image to a ui image named model dot image name and this should be my image view like so and we also need to implement a few more things in this collection view like laying out the actual sub views and whatnot and we also want an initializer so let's see what initializers we have at our disposal so let's see i believe we can get away with using this one so we're going to say init with frame we're going to say super init we want the same one in it with frame passing the frame we're also going to add these uh sub views the label in the image as a sub view to the cell so we're going to say content view add sub view and we want my label and also my image view and we also want to lay out both of these sub views with a frame so we're going to override layout sub views call super in here and basically we want the image to be the top and we want the label to be at the bottom this is yelling at me because once again like the table view if you override the initializer you got to bring in this required one so hit the error and hit fix it'll stub it out for you but basically what i was saying is we want the image view we'll do that one first the frame for it to be c direct and this is going to be an x y within height we'll say x is 5 y is 5. width is going to be let me put this on new lines actually the whistle width is going to be the contentview.frame.size.width minus whoops minus 10. let's get rid of this antivirus popup and the height is going to be frame dot contentview.frame.com dot height minus uh 10 to buffer it or five and then we also want the label to be 50 points high so minus another 50. and now i'm going to copy this and be lazy for the label what we're going to say and this should be width same thing here we're going to say the label is i'm going to line these also the label will be 5 from the left as well the y will be uh contentview.frame.size.height minus 50. so 50 up from the bottom the width is fine here and the height is going to be a fixed 50. like so let me line break these two so they're a little more even and go ahead and hit command b so that's looking good let's go back to the table view cell where we're using the collection view and now what we can say on this cell is cell configure with and pass in the model and what else do we want so let's go ahead and go to our controller and let's uh let's actually just hit run and see what happens so i'm not even sure how far we went in our controller but okay so looks like we have our collection view showing up and it looks really strange and i have a hunch i know why it looks strange and why we have so many but let's uh go to our controller and clean all this stuff up so the first thing actually actually staying in the table view cell you know that we specified the item size for the collection view uh right here to be 170 by 170. so we're gonna go in the uh in the controller we also in our model where did i put the model right here we take a number of rows for the collection view so what we're going to say is we're going to have the height of the table view cell be the number of rows times 170. so that way the collection view can lay everything out properly right now we just say it is 50. so similar to how we do a switch statement in here for number of rows we're going to do a switch statement in here as well and for the list we can simply just return 50. and we don't want to we don't really care about the model so we can do underscore but we do care about in this case the rows and we're going to return 170 times rows and go ahead and hit command b this is yelling because this should be index path dot section like that everything should syntax highlight hit command b one more time let's see what this is yelling at me about this should be so 170 this should this is an integer and should be a float because this expects a float a cg float box so go ahead and wrap that in a cg float hit command b one more time and it compiles and let's see we were also getting way too many uh way too many rows so what we actually we made a mistake so a number of rows for the collection view type is actually not going to be the number of items in the collection view it's going to be one so if the type of the cell for that section is a collection view we only want to show one cell and the reason being is the models are used in the collection view itself but the whole collection view is in one cell hopefully that makes sense uh go ahead and hit command r and let's see what this is looking like now okay making progress so now we only have one cell up here and it has our images our labels but it's kind of large and the reason that it's kind of large this should actually be on two rows i think in our model we set it up to be on two rows so here we provided two but it looks like it's only high enough to have one we need a bit of buffer room and the reason is because our collection view cell height is 170 and we've explicitly used 170 times the number of rows here and it's a good idea to always use buffer for the buffer of the cells themselves so i'm going to bump this to be 180 and hit command r one more time we should be on two rows now like that so looking much much much nicer so now we've got our normal cells here and the table view calls the did select function where we select any of these cells but how do we get the actual contents out when we select something in the collection view how do we relay that to the controller so that's a really important concept so i'm going to put a print here for the did select row and we can say did select normal list item and we're going to go to the table view cell subclass and then here we're going to create a delegate and you'll see why we need a delegate we're going to create a protocol and let's copy this we are going to call this actually let's copy this the name of the class delegate and the function we're going to add in here is did select item with model like that we are going to also say this is any object and we're going to add a public week variable on here called the delegate and it'll be the type of our protocol optional and whenever somebody selects one of our collection view cells we're going to leverage the delegates and we're going to say we're going to call that function we created so whoever is assigned themselves to the delegate they're going to get this call so we're going to have the controller conform to the delegates and here we want to pass the model back to whoever the delegate is just to kind of indicate what thing was tapped and we can get the model uh basically the way we do it here so i'll copy and paste that and be lazy and we can pass the model in like so and now if you come back to the view controller which i think is this class we can say for the collection view cell which is this one right here in our cell for row function we can say cell dot delegate and notice it's that new delegate protocol we created itself now we need to also extend the view controller and conform to that delegate i think it's called collection table view cell delegate and we want that function did select item and i'm simply going to do a print in here selected and let's put in model dot title so go ahead and hit command r now and let's tap on one of these uh cells and see what we get so we'll start with the normal list cells and you'll see that we get this printed out which is exactly what we want and if we tap on any of these collection view cells we get the appropriate thing being printed out because we're reeling via the delegate because we've told each cell that hey i'm the delegate i as in the controller and when we tap on one of the cells the collection view relays via the delegate back to this conformance here so that's how you can set up your uh your actual models and your subclasses and controllers it's a little involved clearly it's a decent amount of code but you know the the ways that you achieve these layouts like this is beautiful this is much nicer than a standard table view cell i think so at least and the last thing i want to do is show you guys how to leverage that video that we brought in this guy and we can put this in a header for the table and i'm a big fan of doing this i do this in a lot of my own apps and it's it just looks really really nice so i'm gonna do that really fast and then we'll call uh wrap up this video and call it uh for this time so let's go ahead and we're gonna create a function and it'll be create whoops create table header and this is going to return a ui view optional and for the table here we're simply going to say table dot table header and then assign it to the result of that function and we brought in the video here and it's video.mp4 so all we're going to want to do is create a player view and stick it into a ui view so player view is a part of i believe av foundation so go ahead and import av foundation and here what we're going to want to do is try to get a path to av foundation uh that file via av foundation so return nil first and foremost so this stops complaining that we're not returning anything that error just went away first thing we want to do is get the path to that file so we're gonna say guard let path equals bundle main and we want path for resource of type it's called video type is mp4 now this thing returns optional which is why we added the guard if we can't get it we're simply going to return nil because we need it to get the actual url then we're going to say let url is url and we want to create a file url with a path whoops we want file url with path then we want to create a av player so we're going to say let player is av player and the player will be created with a url we can pass in the url we're going to say player dot audio or volume that's what we want volume will be zero so we don't randomly play the player uh audio that we want to view uh to actually return so we're gonna say let let's call it header view it's a more appropriate name and the c direct for this guy will be zero by zero with will be the entirety of the screen we want the header to be a square so we're going to say view dot frame.size.with copy that in here as well and now down here instead of returning now return that header view and we want to put the video in the header view so we're going to say let player layer will be av player layer and you can instantiate this with a player so we're going to instantiate that with the player we created here and then we also want to give this a frame so we're going to say the frame of this is header view dot balance and then we want to add this as a sub layer so we're going to say header view add sub layer or header view dot layer add sub layer pass in that player layer and then finally hopefully i don't break anything we want to say player dot play um the other thing you can do which i like to do and i'll do right now is you can set video gravity and this kind of just controls how the i think it's off of the player this actually just controls how the uh video ends up looking in terms of if it scales to fit the size or not and let's see where that property is it might be off of the player view we want the video gravity and there's a couple of things in here i like to do aspect fill so the entire square will be filled let's put this stuff here yeah we can just leave it here it's not really relevant go ahead and hit command b and uh let's run this and see if we get our awesome looking header view so now you can look up here we have our video and it's also playing it's a ferrari commercial if i'm not mistaken but you can what i really want to kind of the takeaway from this video is you can really leverage the table view to make these awesome looking layouts you can have these like headers you can have these collection views you can tap on them and relay like let's say you want to open up another controller and this is actually what the app store does and a bunch of apps like i'm sure you've seen it in facebook or youtube or instagram where like in the app store you have a list of categories and you might have some apps where you can scroll horizontally you might have a video showing for like apple arcade and the coolest thing is this works on ipads and different orientations so here the video doesn't scale because we get to set that up but the collection view you can see takes up the entirety of the screen uh as do the table view cells here and uh yeah you can basically customize this uh to the end of time as much as you want to so that said this video has gotten long enough uh if you haven't smashed that like button already make sure to do so over the youtube algorithm i'm going to upload this code to github and throw the link down below in the description make sure you subscribe if you like these videos i'd love to grow this channel as fast as you guys will kind of help out and let me comment down below if you have any errors or questions just want to say hi love talking to you guys helping you as much as i can thanks for watching and i'll catch you in the next one
Info
Channel: iOS Academy
Views: 9,943
Rating: undefined out of 5
Keywords: swift 5 table view, table view collectionview, collectionView swift 5, swift 5 for beginners, swift for beginners, swift tutorial, swift tableview collectionview, tableview ios, ios development swift, learn swift 5, swift, swift 5, swift wwdc 2020, ios 14 2020 swift, swift 2020, swift make advanced table view, swift mvc, mvvm swift, model view controller swift, swift 5 2020, swift 2020 tutorial, swift UItableview, swiftui tableview, swift tableview 2020, ios app swift, app
Id: C3prKSoT0Eo
Channel Id: undefined
Length: 41min 4sec (2464 seconds)
Published: Wed Jul 08 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.