0

I would like to have a UIButton centred inside my UITableCellView. I've added the necessary code in the tableView cellForRowAt function but I get the error :

The view hierarchy is not prepared for the constraint: When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.

My code is the following :

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

            cell = UITableViewCell(
                style: .default, reuseIdentifier: Id.settingButtonCellIdentifier)
            cell!.backgroundColor = UIColor.clear
            cell!.preservesSuperviewLayoutMargins = false
            cell!.separatorInset = UIEdgeInsets.zero

            let button : UIButton = UIButton(type: UIButtonType.custom) as UIButton
            button.backgroundColor = UIColor.red
            button.setTitle("Click Me !", for: UIControlState.normal)

            cell!.addSubview(button)

            button.translatesAutoresizingMaskIntoConstraints = false
            button.addConstraint(NSLayoutConstraint(item: button, attribute: .leading, relatedBy: .equal, toItem: cell!, attribute: .leading, multiplier: 1, constant: 10))
            button.addConstraint(NSLayoutConstraint(item: button, attribute: .trailing, relatedBy: .equal, toItem: cell!, attribute: .trailing, multiplier: 1, constant: 10))
            button.addConstraint(NSLayoutConstraint(item: button, attribute: .top, relatedBy: .equal, toItem: cell!, attribute: .top, multiplier: 1, constant: 10))
            button.addConstraint(NSLayoutConstraint(item: button, attribute: .bottom, relatedBy: .equal, toItem: cell!, attribute: .bottom, multiplier: 1, constant: 10))
        }

        return cell!
    }

Any help would be appreciated !

113408
  • 3,364
  • 6
  • 27
  • 54
  • Add button in `cell.contentView` as well as Replace `cell` in `toItem` with **cell.contentView** as . @SeanLintern88 why you are creating new cell? you should dequeue it – Prashant Tukadiya Nov 28 '17 at 08:46
  • hmm, your not currently dequeueing cells from the tableview, your just initialising them? I would change to tableView.dequeueCell. But on topic you need to set your buttons autoTranslate off button.translatesAutoresizingMaskIntoConstraints = false – Sean Lintern Nov 28 '17 at 08:47
  • please try this line button.translatesAutoresizingMaskIntoConstraints = false before cell!.addSubview(button) and let me know – Er.Gopal Vasani Nov 28 '17 at 08:52
  • Thanks for your quick replies! Even moving button.translatesAutoresizingMaskIntoConstraints = false before cell!.addSubview(button) doesn't solve the issue. On another topic I'm using dequeue just didn't paste it here to make code focused on the issue – 113408 Nov 28 '17 at 08:58
  • I would recommend to use custom cell loading via xib, then you can set constraints directly in storyboard https://medium.com/@brianclouser/swift-3-creating-a-custom-view-from-a-xib-ecdfe5b3a960 – mihatel Nov 28 '17 at 09:06

1 Answers1

0

Try this

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

        cell = UITableViewCell(
            style: .default, reuseIdentifier: Id.settingButtonCellIdentifier)
        cell!.backgroundColor = UIColor.clear
        cell!.preservesSuperviewLayoutMargins = false
        cell!.separatorInset = UIEdgeInsets.zero

        let button : UIButton = UIButton(type: UIButtonType.custom) as UIButton
        button.backgroundColor = UIColor.red
        button.setTitle("Click Me !", for: UIControlState.normal)

        button.translatesAutoresizingMaskIntoConstraints = false


        cell!.contentView.addSubview(button)

        cell.contentView.addConstraint(NSLayoutConstraint(item: button, attribute: .leading, relatedBy: .equal, toItem: cell.contentView, attribute: .leading, multiplier: 1, constant: 10))
        cell.contentView.addConstraint(NSLayoutConstraint(item: button, attribute: .trailing, relatedBy: .equal, toItem: cell.contentView, attribute: .trailing, multiplier: 1, constant: 10))
        cell.contentView.addConstraint(NSLayoutConstraint(item: button, attribute: .top, relatedBy: .equal, toItem: cell.contentView, attribute: .top, multiplier: 1, constant: 10))
        cell.contentView.addConstraint(NSLayoutConstraint(item: button, attribute: .bottom, relatedBy: .equal, toItem: cell.contentView, attribute: .bottom, multiplier: 1, constant: 10))
    }

    return cell!
}
Keshu R.
  • 5,045
  • 1
  • 18
  • 38