Adding a separator line under custom tableview header in UITableViewCell

I'm trying to add a red line under my custom tableView header.
I'm able to display the custom header, however, I can't seem to get red line under the cell.
I asked around a few places, and I was advised to create a new View and then add constraints as follows:



             let separatorView = UIView(frame: CGRect(x: tableView.separatorInset.left, y: 0, width: 20, height: 1))
            separatorView.backgroundColor = UIColor.red
            separatorView.translatesAutoresizingMaskIntoConstraints  = false
            NSLayoutConstraint.activate([
                separatorView.leadingAnchor.constraint(equalTo:cell.contentView.leadingAnchor),
                separatorView.trailingAnchor.constraint(equalTo:cell.contentView.trailingAnchor),
                separatorView.heightAnchor.constraint(equalToConstant:1),
                separatorView.bottomAnchor.constraint(equalTo:cell.contentView.bottomAnchor)
                ])
            cell.contentView.addSubview(separatorView)





However, this seems to be conflicting with my existing constraints in the custom header cell as I"m getting the error:


UIView:0xxx.leading"> and <NSLayoutXAxisAnchor:0xxxx "UITableViewCellContentView:0xxx.leading"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal.


Here is the full code for the custom header cell:



func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        //let vw = UIView()
        let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! CustomHeaderCell
        
        cell.opt.text = "Some"
        cell.len.text = "LEN"
        cell.wgt.text = "WGT"
        
        if !cell.constraintsInstalled {
            let constraints = [
                cell.stackView.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor),
                cell.stackView.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor),
                cell.stackView.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
                cell.stackView.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor)
            ]
            cell.contentView.addConstraints(constraints) //vw.addSubview(headerCell)
             let separatorView = UIView(frame: CGRect(x: tableView.separatorInset.left, y: 0, width: 20, height: 1))
            separatorView.backgroundColor = UIColor.red
            separatorView.translatesAutoresizingMaskIntoConstraints  = false
            NSLayoutConstraint.activate([
                separatorView.leadingAnchor.constraint(equalTo:cell.contentView.leadingAnchor),
                separatorView.trailingAnchor.constraint(equalTo:cell.contentView.trailingAnchor),
                separatorView.heightAnchor.constraint(equalToConstant:1),
                separatorView.bottomAnchor.constraint(equalTo:cell.contentView.bottomAnchor)
                ])
            cell.contentView.addSubview(separatorView)
        }
        
        //vw.backgroundColor = UIColor.red
        
        return cell
           

You are trying to add constraints before the separatorView is added in the view hierarchy of contentView.


Call addSubveiw before setting constraints:

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! CustomHeaderCell
        
//        ...
        
        if !cell.constraintsInstalled {
//            ...
            let separatorView = UIView(frame: CGRect(x: tableView.separatorInset.left, y: 0, width: 20, height: 1))
            separatorView.backgroundColor = UIColor.red
            separatorView.translatesAutoresizingMaskIntoConstraints  = false
            cell.contentView.addSubview(separatorView) //### <- add to subview before adding constraints
            NSLayoutConstraint.activate([
                separatorView.leadingAnchor.constraint(equalTo:cell.contentView.leadingAnchor),
                separatorView.trailingAnchor.constraint(equalTo:cell.contentView.trailingAnchor),
                separatorView.heightAnchor.constraint(equalToConstant:1),
                separatorView.bottomAnchor.constraint(equalTo:cell.contentView.bottomAnchor)
                ])
        }
        
        //...
        
        return cell
    }
Accepted Answer

Can't you do in IB ?


I tried the following that worked ;

- in the xib for the headerCell

- add a UIView, of desired height

- set its color

- add the constraints to fit at the bottom and full width

Adding a separator line under custom tableview header in UITableViewCell
 
 
Q