Reputation: 966
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
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
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
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