0
votes

I'm following some basic tutorials on how to populate a table view. I have had success with a UITableView and dynamic populating, but following the same steps is not working for me with a UITableViewController.

Any explanation as to why I am having difficulties with the controller?

There doesn't seem to be as much information out there on UITableViewController as there is just UITableView. Is there a reason why everyone seems to be gravitating towards just the UITableView?

For the record, here is the tutorial I am following: http://www.ioscreator.com/tutorials/tableview-tutorial-in-ios8-with-swift

import UIKit

class TestTableViewController: UITableViewController, UITableViewDelegate {

    let tableData = ["One", "Two", "Three"]

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 0
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete method implementation.
        // Return the number of rows in the section.
        return countElements(tableData)
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell

        // Configure the cell...
        cell.textLabel?.text = tableData[indexPath.row]

        return cell
    }


    /*
    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the specified item to be editable.
        return true
    }
    */

    /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    */

    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO if you do not want the item to be re-orderable.
        return true
    }
    */

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */

}

After changing numberOfSectionsInTableView to return 1, this is the error I am receiving.

2015-01-11 18:30:11.557 TableViewTest[30788:8219862] * Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:6116 2015-01-11 18:30:11.560 TableViewTest[30788:8219862] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier reuseIdentifier - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

2
Can you add the code for your table view methods so we can see what you're doing?Matt Cooper
Just added. Someone else added an answer (which seems to have been deleted) suggesting to add UITableViewDelegate. Still does not populate when I run, however.Mathieson
Set delegate and dataSource for your table view. And I think you should return 1 in numberOfSectionsInTableView methodNhut Duong
delegate and dataSource are both connected to the view controller. Entered 1 in numberOfSectionsInTableView method and am getting an error. Investigating the error further. Looks like its complaining about the 'reuseIdentifier' used in the dequeueing call.Mathieson

2 Answers

2
votes

Based on your error message, this is the solution:

In ViewDidLoad(), add:

self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")

See my example project here: https://github.com/ericcgu/EGSwiftTableViewController

1
votes

The reason for your exception is here:

let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell

You didn't ask, but I'll give some background (in case you were wondering why this happened)

To preserve memory and speed up performance, the system places offscreen cells into a reusable pool. If the UITableView needs to display a cell, its data source will check the pool of reusable cells first. If there are any, it (the datasource) will compose the cell and return it to the UITableView.

So, essentially, your datasource object checked the pool for a cell with type "reuseIdentifier", and didn't find any, so an exception was thrown.

You can either register the cell for the reuseIdentifier using the registerClass method of UITableView, or enter in a reuse identifier in the attributes inspector in your storyboard or xib file.

Hope this helps!