Join John Nastos for an in-depth discussion in this video Populating the table data, part of Learn Swift 2: The Basics.
- View Offline
- Now that the storyboard has some table views set up, it's time to start working on populating those tables with data. First I'm going to need classes to represent the View Controllers. So, I'm going to make a few new Swift files to represent the View Controllers that I created in the last video. I'll go to File, New. And create a new file that's a Swift File. The first one that I'll make is called MonthsTableViewController.
And I'll also make one called DaysTableViewController. As well as SingleDayTableViewController. And finally, EventViewController. Now, in each one, I need to define a new class. So, I'm in the MonthsTableViewController.swift file.
And the first that I'm going to do is actually import UIKit, because MonthsTableViewController is going to inherit from UITableViewController which is part of the UIKit framework. Then I'll write class MonthsTableViewContrller, which is a UITableViewController. And I'll leave the implementation blank for right now. Then, I'll copy this information, move over to the DaysTableViewController.swift file, and paste it and change the name of the class.
I'll do the same thing for the SingleDayTableViewController file. And finally, I'll do something slightly different for the EventViewController file. Since it's not a Table View Controller. This time, I'll just define it as a UIViewController. Again with a blank implementation. Now that I have my classes defined, I'm going to go back to the storyboard.
Within the storyboard, I want to make sure that each View Controller has the appropriate swift class associated with it. So, if I open the Months View Controller, you can see under the Identity Inspector Tab, that right now it's a generic UITableViewController. But, I want to set it to MonthsTableViewController. And I want to do similar actions for the other View Controllers. So, I'll set this to DaysTableViewController.
And SingleDayTableViewController. And finally EventViewController. Now, Xcode knows that when the app launches, and these View Controllers are shown, to associate the new classes that I made with those views. When the app launches, this system is going to ask my MonthsTableViewController for some information about what should go in the table. But, I don't have any methods defined yet to handle these requests. Let's go back into the code, and look at what it'll take to start providing the data.
When writing a UITableViewController, there are at least three methods that you need to define and return values for. The first is called numberOfSectionsInTableView. If I start writing that method name, since this is a sub-class of UITableViewController, which implements UITableViewDataSource, where this method comes from, Xcode will auto-complete the method name for me. This method's name is self-explanatory. It returns the number of sections of cells in the table.
I only have one section, so I can simply return 1. Next, I need a method that returns the number of rows in each section. So I'll choose numberOfRowsInEachSection. And for now, I just want a placeholder to test things out. So I'll actually return 1. Finally, I need to implement a method to return the actual cell to be displayed.
So I'll start writing tableView, and the method that I want is cellForRowAtIndexPath. This method needs to return a UITableViewCell. Remember that when I had created my Table View Controllers in the storyboard, each one had a cell that I used to connect the View Controllers together. I'm going to go back into the storyboard now, because I need a way to reference those cells, in order to fill out this method. So, I've selected my MonthsTableViewController.
And I'm going to highlight the cell, under Prototype Cells here. And I'm going to go to the Attributes Inspector. From there I'm going to give it a Reuse Identifier that I can use for my code. And I'll just call it Basic. And, in fact, I'm going to repeat the same process for each of my Table View Controllers. Now, back in my code, I can say let cell = tableView.
dequeueReusableCellWithIdentifier. And pass in that identifier that I just set up in the storyboard. This method returns an optional value. But, I'm confident that I've set everything up correctly, so I'm going to use an ! to implicitly unwrap the optional value. In your app, you may want to adopt a more robust solution for checking to make sure that you got a cell back here. Then, since at this point I just want to test things out, I'll change the title of the cell to test.
And finally, I'll return the cell. At this point, I can launch the app in the simulator. As you can see, the app launches, and this time, my first table has my cell in it. And if I tap it, it brings up the next table, just like I had set up in the storyboard. Now that I've proven that the first table works, it's time to populate it with real data. The first controller is supposed to show a list of months. So, I'm going to create a new array that has the names of the months in it.
Then, in my number of rows method, instead of returning one, like I had done for my test, I want to return the number of months. So, I'll write monthsDataSet.count. Which returns the length of the array. Finally, in the method that returns the cell itself, I don't want to just return test, I want to return the month name. So, I'll set the label equal to monthsDataSet and the index that I want is indexPath.row.
You'll notice that one of the arguments to this method is indexPath. And indexPath.row shows me which row the system is looking to fill in. Now, I can launch my app again in the simulator. This time, you can see, that the months are filled in correctly. At this point, the first table has data, but the others don't. So, I need to go through and implement some methods for them as well. I'll start with the DaysTableViewController. This should show a list of days in the month.
It only has one section. So, I can copy and paste that method here, from my MonthsTableViewController. For the number of rows, I'm going to take a shortcut for our super-simplistic calendar app, and just return 31 here. Since that's the maximum number of days that the month could have. I could always go back and add logic later, to determine how many days each specific month has.
Finally, the cell itself. I'm going to copy and paste the first line of what I had implemented in my MonthsTableViewController. That dequeued the reusable cell. By the way, dequeueResuableCellWithIdentifier is a method that iOS has set up to use with Table Views so that the system can reuse the cells that are created. And it doesn't end up being a huge performance issue to create cells over and over again.
In this method, I want to return the number of the day. So, I'll set the cell.textLabel.text = a string. And Inside that string I want indexPath.row, but because indexPath.row is zero-based, and I want my calendar to start on day one, not zero, I'm going to add 1to the value. And, I'll return my cell.
Time to test in the simulator again. So, my list of months appears. And if I tap January, you can see that it lists 31 days. Lastly, I need to implement methods for my last Table Controller. The SingleDayTableViewController. This should list all of the events for an individual day. First, I'll need to create an array to store the events. So, I'll write var events. And that'll be an array of strings.
And I'll initialize the new array to store that information. Right now, it's an empty array. But it'll be filled later when I add the ability to create events. Then, I'm going to copy and paste my implementation from DaysTableViewController. The number of sections is still the same, just one. For number of rows, I'll want to return the length of the events array. And finally for the cell itself, I'll want to return whatever is in the events array for that particular index.
Once again, I can launch the app in the simulator. I can test the app and see that everything is working, but, of course, the last table, is always empty because I don't yet have a way to add events.
First, learn how to install Xcode, the IDE designed for Apple developers, and use Swift playgrounds, an innovative coding environment that displays results as you code. Author John Nastos then dives deep into Swift syntax: the variables and constants, data types, arrays, loops, classes, and functions that make your apps run. Next, discover how to build an engaging app interface with storyboards and Interface Builder, connect the interface and code, and use table views to present lists. John shows how to store and retrieve data, and interact with Objective-C, the original app development language that still integrates beautifully with Swift. Using the exercise files provided with the course, you'll assemble a complete working app with Swift while gaining the skills to go create the next one on your own.
- Downloading and installing Xcode
- Using Swift playgrounds
- Understanding Swift syntax
- Debugging Swift code
- Controlling flow with expressions, conditional statements, and loops
- Using and writing Swift functions
- Creating classes, structs, and enums
- Using storyboards in Interface Builder
- Building an app with table views
- Storing and retrieving data
- Interacting with Objective-C