0

My tableview cell subtitles aren't showing when I use this:

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

var cell:UITableViewCell?

if tableView.tag == 1 {

    guard let latestCell = tableView.dequeueReusableCell(withIdentifier: "latestCell") else {
        return UITableViewCell(style: .subtitle, reuseIdentifier: "latestCell")
    }
    latestCell.textLabel?.text = latest[indexPath.row]

    latestCell.detailTextLabel?.text = latestSub[indexPath.row]

    latestCell.accessoryType = .disclosureIndicator

    return latestCell
   }
}

But then if I use this:

else if tableView.tag == 2 {

    let olderCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "olderCell")



    olderCell.textLabel?.text = older[indexPath.row]

    olderCell.detailTextLabel?.text = olderSub[indexPath.row]

    olderCell.accessoryType = .disclosureIndicator

    return olderCell
  } else {
    return cell!
  }
}

The subtitles load perfectly, but after I close the app and reload the view, the app autoquits without giving a crash log or taking me to the debugging-tab.

I know that the arrays from which the data comes from are fine, and I think that I've set up everything right in the storyboard. A lot of similar questions have already been posted on the subject, but they all seem to come down to forgetting to set the cellStyle to .subtitle. Thanks in advance for any help I get!

BTW. My regular cell titles are working just like I want them to. No problem there.

EDIT:

I think the problem is that I can create a default-styled cell with no problem. But then when I try to set the style to .subtitle, it loads correctly the first time but when opening the second time, it crashes. Is there a way to use these both declarations together in a way that they don't eliminate each other out;?

guard let latestCell = tableView.dequeueReusableCell(withIdentifier: "latestCell") else {
    return UITableViewCell(style: .subtitle, reuseIdentifier: "latestCell")
}

and:

let latestCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "latestCell")

storyboard

saurabh
  • 6,687
  • 7
  • 42
  • 63
Tuomax
  • 31
  • 1
  • 5
  • In you guard let stuff, you return the cell without even setting its properties. The second code don't reuse cell (not recommended). – Larme Feb 19 '17 at 11:38
  • friend can i ask you ? Are you using two tableview ? – Mukesh Lokare Feb 19 '17 at 11:49
  • Yes, I am using two. – Tuomax Feb 19 '17 at 13:49
  • I solved the problem, turned out that the tableview wasn't reloading properly. After I fixed the order of the statements that activate tableview, it fixed it. Thanks for replying everyone! – Tuomax Feb 19 '17 at 17:25

5 Answers5

1

Do it like this:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("latestCell") as UITableViewCell

    cell.textLabel?.text = latest[indexPath.row]
    cell.detailTextLabel?.text = latestSub[indexPath.row]
    cell.accessoryType = .disclosureIndicator

    return cell

}

Mark this as solution/upvote if this solved your problem.

1

Old but...

I think the problem was :

guard let latestCell = tableView.dequeueReusableCell(withIdentifier: "latestCell") else {
    return UITableViewCell(style: .subtitle, reuseIdentifier: "latestCell")
}

will return an "empty" cell.

So.. just like :

var latestCell = tableView.dequeueReusableCell(withIdentifier: "latestCell")

if latestCell == nil {
   latestCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "latestCell")
}

// your stuff
Axel Guilmin
  • 11,454
  • 9
  • 54
  • 64
dasoli
  • 11
  • 5
1

Ran into this question today as well. I assume the original poster found the answer, but for others that run into this thread in the future here is how I solved this. Note this link/thread explains addition methods of solving as well. How to Set UITableViewCellStyleSubtitle and dequeueReusableCell in Swift?

Environment: Swift 5.0 and Xcode Version 10.2.1.

Explanation: I solved this by subclassing UITabelViewCell and initializing it with the .subtitle type (see code below). Note the .subtitle in the super.init method.

Once you have the subclass don't forget to register CustomCell to your tableView and downcast as CustomCell in your tableView method cellForRowAt.

class CustomCell: UITableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Here is the code for the cellForRowAt method, which has the titleLabel and the detailTextLabel(subtitle) properties. Note the downcast "as! CustomCell".

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

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

            cell.textLabel?.text = someArray[indexPath.row].title // Note someArray would have to be replaced with your array of strings.
            cell.detailTextLabel?.text = someArray[indexPath.row].subtitle // Note someArray would have to be replaced with your array of strings.

        return cell
    }
Ben Oveson
  • 49
  • 3
0

Easiest solution:

Design both cells in Interface Builder directly in the table view(s), set the style and the accessory view to your desired values and add the identifiers.

Then the code can be reduced to.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   switch tableView.tag {
   case 1:
   let latestCell = tableView.dequeueReusableCell(withIdentifier: "latestCell" for: indexPath)
      latestCell.textLabel!.text = latest[indexPath.row]
      latestCell.detailTextLabel!.text = latestSub[indexPath.row]
      return latestCell

   case 2:
      let olderCell = tableView.dequeueReusableCell(withIdentifier: "olderCell" for: indexPath)
      olderCell.textLabel!.text = older[indexPath.row]
      olderCell.detailTextLabel!.text = olderSub[indexPath.row]
      return olderCell

   default: 
      fatalError("That should never happen")
   }

}

Since the cells are predefined to subtitle style, both textLabel and detailTextLabel are guaranteed to exist and can be safely unwrapped.

However what is the significant difference between the cells. From the given code you can actually use one cell (identifier cell). That can make the code still shorter:

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

   let cell = tableView.dequeueReusableCell(withIdentifier: "cell" for: indexPath)

   if tableView.tag == 1 {
      cell.textLabel!.text = latest[indexPath.row]
      cell.detailTextLabel!.text = latestSub[indexPath.row]
   } else {
      cell.textLabel!.text = older[indexPath.row]
      cell.detailTextLabel!.text = olderSub[indexPath.row]
   }
   return cell
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • This doesn't set the style to subtitle, so no luck there, and I had already set my cells properly in the storyboard. But thanks for trying! – Tuomax Feb 19 '17 at 13:44
  • If the style is set in Interface Builder it must appear in the reused cell. – vadian Feb 19 '17 at 13:46
  • What do you mean by that? I'm sorry that I don't quite understand. If you mean the style set in the cell in storyboard, then yes, it appears there. – Tuomax Feb 19 '17 at 13:57
  • Yes, if you set the style in storyboard it will appear and you don't need to set it in code. But you have to design the cell in both table views. – vadian Feb 19 '17 at 13:58
  • I edited the post, there's a link to a screenshot of my storyboard, I set both of the prototype cells that way, it still isn't working. – Tuomax Feb 19 '17 at 14:04
  • Since you have two table views anyway I recommend to use the `latestCell ` / `olderCell` identifier. – vadian Feb 19 '17 at 14:07
  • Oh, I'm sorry I must have mixed up some of these answers, actually the subtitles show, but when I close the app and open it up again, it quits. Sorry for the confusion. – Tuomax Feb 19 '17 at 14:09
  • Then it's most likely not related to the table view design. – vadian Feb 19 '17 at 14:10
  • Well do you know what it's about then? Thanks for being so active! – Tuomax Feb 19 '17 at 14:12
  • I'm afraid no. Use the debugger. Set breakpoints to figure it out. – vadian Feb 19 '17 at 14:14
0
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") //replace "Cell" with your identifier
    cell.textLabel = yourTitleArray[indexPath.row]
    cell.detailTextLabel = yourSubtitleArray[indexPath.row]
    return cell!
}
Toma
  • 2,764
  • 4
  • 25
  • 44