daniel
daniel

Reputation: 966

Table view cells not showing in simulator

I seem to have done everything I'm supposed to, but my table view cells aren't showing when I use two different subclasses of UITableViewCell each with an xib file, except for the integer values I assigned to textLabel!.text at the end of tableView(_:cellForRowAt:) right before the return statement. What am I doing wrong?

Here is my code:

import UIKit

class DetailTableViewController: UITableViewController {

    let items = [0, 1]

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(DueDateSwitchTableViewCell.self, forCellReuseIdentifier: "DueDateSwitchTableViewCell")

        let xibDueDateSwitchTableViewCell = UINib(nibName: "DueDateSwitchTableViewCell", bundle: Bundle.main)

        tableView.register(xibDueDateSwitchTableViewCell, forCellReuseIdentifier: "DueDateSwitchTableViewCell")

        tableView.register(DueDatePickerTableViewCell.self, forCellReuseIdentifier: "DueDatePickerTableViewCell")

        let xibDueDatePickerTableViewCell = UINib(nibName: "DueDatePickerTableViewCell", bundle: Bundle.main)

        tableView.register(xibDueDatePickerTableViewCell, forCellReuseIdentifier: "DueDatePickerTableViewCell")

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        print("tableView(_:cellForRowAt:)", "indexPath.row=", indexPath.row)

        let cell = UITableViewCell()

        switch indexPath.section {

        case 0:

            print("\tcase 0")

            let cell = tableView.dequeueReusableCell(withIdentifier: "DueDateSwitchTableViewCell", for: indexPath) as! DueDateSwitchTableViewCell

            cell.label.text = String(items[indexPath.section].hashValue)

            cell.backgroundColor = UIColor.yellow

        case 1:

            print("\tcase 1")

            let cell = tableView.dequeueReusableCell(withIdentifier: "DueDatePickerTableViewCell", for: indexPath) as! DueDatePickerTableViewCell

            cell.label.text = String(items[indexPath.section].hashValue)

            cell.datePicker.date = Date()

        default:

            break

        }

        cell.textLabel!.text = String(items[indexPath.section].hashValue)

        return cell

    }

}

Upvotes: 1

Views: 983

Answers (3)

Suhit Patil
Suhit Patil

Reputation: 12023

If you're using xibs the no need to register UITableViewCell subclass in register method just register using nib

override func viewDidLoad() {
        super.viewDidLoad()

        let xibDueDateSwitchTableViewCell = UINib(nibName: "DueDateSwitchTableViewCell", bundle: Bundle.main)

        tableView.register(xibDueDateSwitchTableViewCell, forCellReuseIdentifier: "DueDateSwitchTableViewCell")

        let xibDueDatePickerTableViewCell = UINib(nibName: "DueDatePickerTableViewCell", bundle: Bundle.main)

        tableView.register(xibDueDatePickerTableViewCell, forCellReuseIdentifier: "DueDatePickerTableViewCell")

    }

in cellForRowAt method you're returning a empty cell by assigning cell to UITableViewCell(), change it return a CustomCells which you have registered in ViewDidLoad based on indexPath.section as numberOfSection method returning 2 sections

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch indexPath.section {
            case 0:
                let cell = tableView.dequeueReusableCell(withIdentifier: "DueDateSwitchTableViewCell", for: indexPath) as! DueDateSwitchTableViewCell
                cell.label.text = String(items[indexPath.section].hashValue)
                cell.backgroundColor = UIColor.yellow
                return cell
            case 1:
                let cell = tableView.dequeueReusableCell(withIdentifier: "DueDatePickerTableViewCell", for: indexPath) as! DueDatePickerTableViewCell
                cell.label.text = String(items[indexPath.section].hashValue)
                cell.datePicker.date = Date()
            return cell
            default:
                fatalError("Unexpected section \(indexPath.section)")
        }
    }

Upvotes: 0

iPatel
iPatel

Reputation: 47049

Change in ViewDidLoad Method

let nib = UINib(nibName: "DueDateSwitchTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "DueDateSwitchTableViewCell")

let nib = UINib(nibName: "DueDatePickerTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "DueDatePickerTableViewCell")

And Change in cellForRowAtIndexPath dataSource method

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {    
      print("tableView(_:cellForRowAt:)", "indexPath.row=", indexPath.row)        
      if indexPath.section == 0 {    
            let cell = tableView.dequeueReusableCell(withIdentifier: "DueDateSwitchTableViewCell", for: indexPath) as! DueDateSwitchTableViewCell    
            cell.label.text = String(items[indexPath.section].hashValue)   
            cell.backgroundColor = UIColor.yellow
            cell.textLabel!.text = String(items[indexPath.section].hashValue)
            return cell
        }
        else {
             let cell = tableView.dequeueReusableCell(withIdentifier: "DueDatePickerTableViewCell", for: indexPath) as! DueDatePickerTableViewCell
             cell.label.text = String(items[indexPath.section].hashValue)
             cell.datePicker.date = Date()
             cell.textLabel!.text = String(items[indexPath.section].hashValue)
             return cell
        }
    }
}

Upvotes: 0

rmaddy
rmaddy

Reputation: 318774

The cells you create inside each case statement is ignored and left unused. Your return cell line is returning the first cell variable which is your empty cell.

Since you only have two possible cells, I suggest redoing your code as follows:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "DueDateSwitchTableViewCell", for: indexPath) as! DueDateSwitchTableViewCell
        cell.label.text = String(items[indexPath.section].hashValue)
        cell.backgroundColor = UIColor.yellow

        return cell
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "DueDatePickerTableViewCell", for: indexPath) as! DueDatePickerTableViewCell
        cell.label.text = String(items[indexPath.section].hashValue)
        cell.datePicker.date = Date()

        return cell
    }
}

You also need to fix your viewDidLoad. There should only be one call to register per reuse identifier. You have two each.

Upvotes: 1

Related Questions