I have created UITableviewCell programmatically and trying to load in table view Cell has just one imageView and UIlabel.
Although the UI looks fine , but I am seeing this warning :
Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x60000147f200 V:|-(0)-[UIView:0x7f897ea24a00] (active, names: '|':SampleTest.MemesTableViewCell:0x7f897ea2aaf0 )>",
"<NSLayoutConstraint:0x60000147f2f0 UIView:0x7f897ea24a00.bottom == SampleTest.MemesTableViewCell:0x7f897ea2aaf0.bottom (active)>",
"<NSLayoutConstraint:0x60000147f570 V:|-(10)-[UIImageView:0x7f897ea18170] (active, names: '|':UIView:0x7f897ea24a00 )>",
"<NSLayoutConstraint:0x60000147f110 UIImageView:0x7f897ea18170.height == 80 (active)>",
"<NSLayoutConstraint:0x60000147eb70 UIImageView:0x7f897ea18170.bottom == UIView:0x7f897ea24a00.bottom - 20 (active)>",
"<NSLayoutConstraint:0x60000147f4d0 'UIView-Encapsulated-Layout-Height' SampleTest.MemesTableViewCell:0x7f897ea2aaf0.height == 44 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60000147f110 UIImageView:0x7f897ea18170.height == 80 (active)>
My Code:
import UIKit
class MemesTableViewCell : UITableViewCell {
var contentHolderView : UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
private let nameLabel = UILabel()
var memeImageView = UIImageView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
contentHolderView.backgroundColor = UIColor.red
addSubview(contentHolderView)
contentHolderView.addSubview(nameLabel)
contentHolderView.addSubview(memeImageView)
nameLabel.translatesAutoresizingMaskIntoConstraints = false
memeImageView.translatesAutoresizingMaskIntoConstraints = false
memeImageView.contentMode = .scaleAspectFit
NSLayoutConstraint.activate([
//layout contentView
contentHolderView.topAnchor.constraint(equalTo: self.topAnchor,constant: 0),
contentHolderView.bottomAnchor.constraint(equalTo: bottomAnchor,constant: 0),
contentHolderView.leadingAnchor.constraint(equalTo: leadingAnchor,constant: 0),
contentHolderView.trailingAnchor.constraint(equalTo: trailingAnchor,constant: 0),
memeImageView.topAnchor.constraint(equalTo: contentHolderView.topAnchor, constant: 10),
memeImageView.leadingAnchor.constraint(equalTo: contentHolderView.leadingAnchor, constant: 10),
memeImageView.widthAnchor.constraint(equalToConstant: 80),
memeImageView.heightAnchor.constraint(equalToConstant: 80),
nameLabel.leadingAnchor.constraint(equalTo: memeImageView.trailingAnchor, constant: 10),
nameLabel.topAnchor.constraint(equalTo: contentHolderView.topAnchor, constant: 12)
])
if let lastView = contentHolderView.getTheLastAddedView() {
lastView.bottomAnchor.constraint(equalTo: contentHolderView.bottomAnchor, constant: -20).isActive = true
}
self.layoutIfNeeded()
}
}
extension UIView {
func getTheLastAddedView()->UIView?{
if let lastView = self.subviews.last{
return lastView
}
return nil
}
}
I like to know how can this warning be fixed?
CodePudding user response:
This is a common situation when using cells with embedded views.
As you've seen, the UI result looks fine -- because auto-layout will attempt to recover by breaking constraint, and then it re-establishes the constraint.
To get rid of the warnings, give the constraint that ends up defining the height a less-than-required priority.
So, change the end of your setupView()
func to this:
if let lastView = contentHolderView.getTheLastAddedView() {
let c = lastView.bottomAnchor.constraint(equalTo: contentHolderView.bottomAnchor, constant: -20)
c.priority = .required - 1
c.isActive = true
//lastView.bottomAnchor.constraint(equalTo: contentHolderView.bottomAnchor, constant: -20).isActive = true
}
// this is not needed
//self.layoutIfNeeded()
As a side note, a cell's subviews should not be added to, or constrained to, the cell itself. You should use the cell's .contentView
instead:
contentView.addSubview(contentHolderView)
and then:
NSLayoutConstraint.activate([
//layout contentView
contentHolderView.topAnchor.constraint(equalTo: contentView.topAnchor,constant: 0),
contentHolderView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor,constant: 0),
contentHolderView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor,constant: 0),
contentHolderView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,constant: 0),