39

I have a tableView set up so that when a cell is touched, it expands in height to reveal more information. The tableView has 5 sections.

I have a bug: when a cell expands, all headersCells below that cell go invisible. The console outputs the following: "[31233:564745] no index path for table cell being reused"

In my storyboard I have 2 custom cells : "myCell" for the data bearing cells, and "headerCell" for the headers.

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

   let thisGoal : GoalModel = goalArray[indexPath.section][indexPath.row]


    if self.currentPath != nil && self.currentPath == indexPath  {
        self.currentPath = nil
    } else {
        self.currentPath = indexPath
    }
    tableView.beginUpdates()
    tableView.endUpdates()
}

If I enter tableView.reloadData() in between the begin/end updates, it functions properly, although the header background turns black, and loses animation.

I have all of the stuff for headers declared in: func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?

what am I missing? I'd really like the tableView to still have animations, and keep the background clearColor().

Thanks in advance. I did read through the objective C answers, but couldn't get them to work for me. I'd really appreciate some SWIFT help.

I think the problem is the no index path for table cell being reused.

Phontaine Judd
  • 308
  • 5
  • 14
Mason Ballowe
  • 1,749
  • 2
  • 10
  • 19

6 Answers6

124

I found an answer in the console output. Use this code in the header function:

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 

Do not return your headerCell, or your reusable identifier. Return the reuseIdentifier.contentView. For me it's: return headerCell!.contentView.

Cesare
  • 8,326
  • 14
  • 64
  • 116
Mason Ballowe
  • 1,749
  • 2
  • 10
  • 19
18

Just to add, I was baffled for WAY longer than I should have been as to why I couldn't refer to the contentView of my cell, when I could quite clearly see it was there. My custom class (using UITableViewCell rather than UITableViewHeaderFooterView) would return a fatal error each time. Therefore make sure any custom styling is setup under UITableViewHeaderFooterView class like:

class CustomHeaderCell: UITableViewHeaderFooterView {

You will also need to register the resuableIdentifer like this:

tableView.registerNib(UINib(nibName: "HeaderCell", bundle: nil), forHeaderFooterViewReuseIdentifier: "CellHeader")

Then this bad boy:

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerCell = tableView.dequeueReusableHeaderFooterViewWithIdentifier("CellHeader") as! CustomHeaderCell!
    return headerCell!.contentView
}
David West
  • 1,450
  • 1
  • 17
  • 27
  • no need to add UITableViewHeaderFooterView if the class is extended in UITableViewController. thank you for the headerCell!.contentView answer – Led Aug 11 '16 at 04:05
  • It is not compulsory to use UITableViewHeaderFooterView, I am using UITableViewCell class but the key was to return the cell.contentView rather the cell itself. Returning the whole cell was causing the issue for me. – Satheesh Oct 16 '17 at 10:37
  • 4
    adding .contentView saved my day – Grease Nov 15 '17 at 12:58
  • 1
    This is the best answer! Never make your headers like a cells guys! – WorieN May 31 '18 at 13:47
11

Since I'm not at 50 reputation yet, I can't comment on the previous answer, so I apologize for listing this as another answer.

Returning the ContentView will make the function work but will remove all formatting done to the reuseIdentifier (headerCell)

headerCell.backgroundColor = UIColor.cyanColor()

This will NOT provide a Cyan color to your headerCell

To fix this, just add the ".contentView" to your formatting lines

headerCell.contentView.backgroundColor = UIColor.cyanColor()
Nathan Wharry
  • 121
  • 1
  • 5
5

Table view headers in 2 tables disappeared when I converted my app to IOS 10 - I found the reason in Apple developer API documentation on table headers. When I added the following, the missing headers reappeared!

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
return 44 // where 44 is the header cell view height in my storyboard
}
toha
  • 4,097
  • 3
  • 31
  • 49
Frans
  • 51
  • 1
  • 2
4

You could wrap the TableViewCell inside an UIView

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  let containerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 50)) // 50 = Header height

  guard let headerCell = tableView.dequeueReusableCell(withIdentifier: "MyHeaderView") as? MyHeaderView else { fatalError(" Failed to load MyHeaderView") }
  headerCell.frame = containerView.bounds
  containerView.addSubview(headerCell)

  return containerView
}
Krishna Raj Salim
  • 7,061
  • 5
  • 29
  • 62
dev
  • 1,166
  • 11
  • 23
3

I had the same bug because I was returning a cell using dequeue method instead of a UITableViewHeaderFooterView.

Solution:

  • Add a view outside of the view hierarchy
  • Set the type to UITableViewHeaderFooterView
  • Customize
  • Link to an @IBOutlet
  • In func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? return the outlet

Common pitfalls:

Don't forget to set the header sizes Don't forget to set the outlet as strong.

Antzi
  • 11,625
  • 6
  • 40
  • 66