I\'d like a UITableView
with subtitle
-style cells that use dequeueReusableCellWithIdentifier
.
My original Objective-C code was
Basically the same as other answers, but I get around dealing with nasty optionals (you can't return nil
from -tableView:cellForRow:atIndexPath:
in Swift) by using a computed variable:
Swift 3
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell") else {
// Never fails:
return UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "UITableViewCell")
}
return cell
}()
// (cell is non-optional; no need to use ?. or !)
// Configure your cell:
cell.textLabel?.text = "Key"
cell.detailTextLabel?.text = "Value"
return cell
}
Edit:
Actually, it would be better to dequeue the cell using: tableView.dequeueReusableCell(withIdentifier:for:)
instead.
This later variant of the function automatically instantiates a new cell if no one is available for reusing (exactly what my code does explicitly above), and therefore never returns nil
.
If you'd rather avoid optionality, you can make a subclass of UITableViewCell that looks something like this:
class SubtitleTableViewCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Then register it using:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(SubtitleTableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
}
This allows your cell customization code to be really nice:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
cell.textLabel?.text = "foo"
cell.detailTextLabel?.text = "bar"
return cell
}
Make sure that you are not registering any cell to the tableview.
If you did so, dequeueReusableCellWithIdentifier will always give a non optional cell so UITableViewCellStyle.Subtitle will never initiate.
If you are not using your own Custom Cell. Simply register UITableViewCell through code. Then you can prefer code.
Else select storyboard, select your TableViewCell -> Goto Attribute Inspector and choose the desired style as shown below.
Just building upon memmons' answer by cleaning it up Swift 2 style...
let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) ?? UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
cell.detailTextLabel?.text = "some text"
return cell
Swift 3:
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
cell.detailTextLabel?.text = ""
return cell
Perfect as suggested by Michael G. Emmons, but in Xcode 6.1 using
if !cell { .....
I get this error:
Optional type '@|value UITableViewCell?' cannot be used as boolean ; test for '!= nil' instead
The accepted syntax is:
if cell == nil { ...