Reputation: 5495
I am trying to add constraints to subviews in my UITableViewCell, but am getting the error Unable to interpret '|' character, because the related view doesn't have a superview
Here is my custom UITableViewCell
class:
class MessageTableViewCell: UITableViewCell {
var titleLabel: UILabel {
get {
let titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.font = UIFont.boldSystemFont(ofSize: self.defaultFontSize)
return titleLabel
}
}
var bodyLabel: UILabel {
get {
let bodyLabel = UILabel()
bodyLabel.translatesAutoresizingMaskIntoConstraints = false
bodyLabel.font = UIFont.systemFont(ofSize: self.defaultFontSize)
return bodyLabel
}
}
var thumbnailView: UIImageView {
get {
let thumbnailView = UIImageView()
thumbnailView.translatesAutoresizingMaskIntoConstraints = false
thumbnailView.layer.cornerRadius = CGFloat(TableViewCellArrangements.kMessageTableViewCellAvatarHeight/2.0)
thumbnailView.layer.masksToBounds = true
return thumbnailView
}
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configureSubviews()
}
private func configureSubviews() {
self.contentView.addSubview(thumbnailView)
self.contentView.addSubview(titleLabel)
self.contentView.addSubview(bodyLabel)
let views: [String : Any] = ["thumbnailView" : thumbnailView,
"titleLabel" : titleLabel,
"bodyLabel" : bodyLabel]
let metrics: [String : Any] = ["thumbSize" : TableViewCellArrangements.kMessageTableViewCellAvatarHeight,
"padding" : 15,
"right" : 10,
"left" : 5]
//The next line throws an exception. In fact, all the `let constraint` code will throw exceptions
let constraint1 = NSLayoutConstraint.constraints(withVisualFormat: "H:|-left-[thumbnailView(thumbSize)]-right-[titleLabel(>=0)]-right-|", options: .alignAllLeft, metrics: metrics, views: views)
contentView.addConstraints(constraint1)
let constraint2 = NSLayoutConstraint.constraints(withVisualFormat: "H:|-left-[thumbnailView(thumbSize)]-right-[bodyLabel(>=0)]-right-|", options: .alignAllLeft, metrics: metrics, views: views)
contentView.addConstraints(constraint2)
let constraint3 = NSLayoutConstraint.constraints(withVisualFormat: "V:|-right-[thumbnailView(thumbSize)]-(>=0)-|", options: .alignAllLeft, metrics: metrics, views: views)
contentView.addConstraints(constraint3)
if self.reuseIdentifier == TableViewCellArrangements.MessengerCellIdentifier {
let constraint4 = NSLayoutConstraint.constraints(withVisualFormat: "V:|-right-[titleLabel(20)]-left-[bodyLabel(>=0@999)]-left-|", options: .alignAllLeft, metrics: metrics, views: views)
contentView.addConstraints(constraint4)
} else {
let constraint5 = NSLayoutConstraint.constraints(withVisualFormat: "V:|[titleLabel]|", options: .alignAllLeft, metrics: metrics, views: views)
contentView.addConstraints(constraint5)
}
}
As noted above, the constraint line is where the exception is thrown. However, I have added the subviews to the contentView prior to setting the constraints, and so am confused why it thinks there is superview.
Thanks!
Upvotes: 1
Views: 237
Reputation: 77476
You are re-creating a new instance of the elements each time they are referenced. Try it like this:
var xtitleLabel: UILabel?
var titleLabel: UILabel {
get {
if xtitleLabel == nil {
xtitleLabel = UILabel()
}
xtitleLabel?.translatesAutoresizingMaskIntoConstraints = false
xtitleLabel?.font = UIFont.boldSystemFont(ofSize: self.defaultFontSize)
return xtitleLabel!
}
}
You still refer to titleLabel
throughout your code - this just results in a "create once" process.
Upvotes: 1