I have a custom cell 'CustomCell' that I wish to compose based on a custom data element. I am trying to add subviews to CustomCell but for those subviews loaded from a xib (https://stackoverflow.com/a/26326006/3546621), I can't figure out how to layout them into the cell's contentView; i.e programmatically setting their frame nor adding constraints seem to work. ( CustomCell has no xib attached, every subviews is loaded programmatically. Some of these subview are loaded from xib.)
For example, here is my custom cell. It has two subviews, a yellowView initialized with UIView(frame: CGRect()) and right below a blueView initialized with UIView.fromNib.
This is BlueView.xib
I am not succeeding at placing blueView below yellowView, instead I have the blueView being stacked on top of the yellowView:
class CustomCell: UITableViewCell {
let yellowView: UIView = UIView()
let blueViewFromXib: BlueView = UIView.fromNib()
override init(style: UITableViewCellStyle, reuseIdentifier: String?){
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
fun configureForData(custom: Custom){
yellowView.backgroundColor = UIColor.yellowColor()
yellowView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(yellowView)
blueView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(blueView)
layoutIfNeeded()
}
override func layoutSubviews() {
super.layoutSubviews()
let height = NSLayoutConstraint(item: contentView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 80)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.addConstraint(height)
yellowView.frame = CGRect(x: 0, y: 0, width: contentView.frame.width, height: 40)
// I want to add the blueView at the bottom of the yellowView
// Option 1: not working
blueView.frame = CGRect(x: 0, y: 40, width: contentView.frame.width, height: 40)
// Option 2: not working
let top = NSLayoutConstraint(item: blueView, attribute: .Top, relatedBy: .Equal, toItem: contentView, attribute: .Top, multiplier: 1, constant: 40)
let bottom = NSLayoutConstraint(item: blueView, attribute: .Bottom, relatedBy: .Equal, toItem: contentView, attribute: .Bottom, multiplier: 1, constant: 0)
let leading = NSLayoutConstraint(item: blueView, attribute: .Leading, relatedBy: .Equal, toItem: contentView, attribute: .Leading, multiplier: 1, constant: 0)
let trailing = NSLayoutConstraint(item: blueView, attribute: .Trailing, relatedBy: .Equal, toItem: contentView, attribute: .Trailing, multiplier: 1, constant: 0)
contentView.addConstraints([top, bottom, leading, trailing])
}
}
class BlueView: UIView {
// the project includes a BlueView.xib which is simply a UIView whose background color is blue
}
View Controller
override func viewDidLoad(){
super.viewDidLoad()
tableView.delegate = self
tableView.datasource = self
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 80
tableView.registerClass(CustomCell.self, forCellReuseIdentifier: "CustomCell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let custom = customs[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomCell
cell.configureForData(custom)
return cell
}