Bonjour,
J’ai un problème de contrainte dans un UITableViewCell
dynamique.
[LayoutConstraints] 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:0x283f610e0 UIView:0x10473cab0.height == 20 (active)>",
"<NSLayoutConstraint:0x283f58d20 'UISV-fill-proportionally' UIView:0x10473cab0.height == 0 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x283f58d20 'UISV-fill-proportionally' UIView:0x10473cab0.height == 0 (active)>
Je m’explique ma UITableViewCell
est dynamique car une partie est construite via l’IB et je la modifie ajoutant des UIView
dans une UIStackView en Swift.
Pour faire simple ma UITableViewCell
se compose de 3 Parties : un HEADER, un CONTENT et un FOOTER.
En gros je modifie simplement le CONTENT qui est ma UIStackView
qui a pour contrainte :
- un Space Top (4) -> HEADER
- un Space Bottom (4) -> FOOTER
- un Leading (0) -> parentView
- un Trailing (0) -> parentView
- un Height (0) -> je pense que c’est ce qui pose problème
Et voilà le code qui me permet de modifier ma UITableViewCell (Simplifier) :
class MyTableViewCell: UITableViewCell {
//MARK: - ATTRIBUTES
var lecons : [Lecon]?
//MARK: - IBOUTLETS
@IBOutlet weak var ui_numSeanceLabel: UILabel! //HEADER
@IBOutlet weak var ui_typeSeanceLabel: UILabel! //HEADER
@IBOutlet weak var ui_dateSeanceLabel: UILabel! //HEADER
@IBOutlet weak var ui_formateurSeanceLabel: UILabel! //HEADER
@IBOutlet weak var ui_contentStackView: UIStackView! //CONTENT
@IBOutlet weak var ui_commentLabel: UILabel! //FOOTER
@IBOutlet weak var ui_contentStackViewHeightConstraint: NSLayoutConstraint! //Contrainte Height de la UIStackView
//MARK: - METHODS
//Fonction appeler dans la tableview
func updateCell(){
//reinitialise la UIStacKView
ui_contentStackView.subviews.forEach { view in
view.removeFromSuperview()
}
ui_contentStackViewHeightConstraint.constant = 0
ui_numSeanceLabel.text = " 3 "
ui_typeSeanceLabel.text = " "
ui_dateSeanceLabel.text = " 14 dec. 2018 "
ui_formateurSeanceLabel.text = "par Paul"
ui_commentLabel.text = "∅ - Aucune observation"
setupContentViewWithLecon()
}
private func setupContentViewWithLecon(){
guard let objectifs = lecon?.objectif else { return }
guard !objectifs.isEmpty else { return }
var heightContent : CGFloat = 0.0
var numComp : Int = 0
var numCompBefore : Int = -1
objectifs.forEach{ competence in
if let obj = competence.objectif {
numComp = competence.numCompetence ?? 0
let colorsOfSubviews = setColorObjectif(competenceId: numComp)
if(numComp != numCompBefore) {
heightContent += 20.0
ui_contentStackViewHeightConstraint.constant = heightContent
let view = setCompetenceTilteItem(pText: "Competence \(numComp)", pBgColor: colorsOfSubviews.0, pTextColor: UIColor.white)
ui_contentStackView.addArrangedSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
ui_contentStackView.addConstraint(NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20))
numCompBefore = numComp
}
heightContent += 80.0
ui_contentStackViewHeightConstraint.constant = heightContent
let compView = setCompetenceItem(pNumValid: competence.niveau ?? 0, pText: obj.description ?? "" ,pLetter: obj.titre ?? "0", pHasSeparator: true, pBgColor: colorsOfSubviews.1 , fgColor: colorsOfSubviews.0)
ui_contentStackView.addArrangedSubview(compView)
compView.translatesAutoresizingMaskIntoConstraints = false
ui_contentStackView.addConstraint(NSLayoutConstraint(item: compView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 80))
numCompBefore = numComp
}
}
}
private func setColorObjectif(competenceId : Int) -> (UIColor,UIColor) {
let colors : (UIColor, UIColor)
switch competenceId {
case 2 :
colors = (UIColor.C2Dark,UIColor.C2Light)
case 3 :
colors = (UIColor.C3Dark,UIColor.C3Light)
case 4 :
colors = (UIColor.C4Dark,UIColor.C4Light)
default:
colors = (UIColor.C1Dark,UIColor.C1Light)
}
return colors
}
private func setCompetenceTilteItem(pText: String, pBgColor: UIColor, pTextColor: UIColor) -> UIView{
let view = UIView()
view.backgroundColor = pBgColor
let label = UILabel()
view.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.text = pText
label.textColor = pTextColor
view.addConstraint(NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 8))
view.addConstraint(NSLayoutConstraint(item: label, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: -8))
view.addConstraint(NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0))
return view
}
private func setCompetenceItem(pNumValid: Int, pText: String, pLetter: String = "", pHasSeparator: Bool, pBgColor: UIColor, fgColor: UIColor) -> UIView {
let view = UIView()
view.backgroundColor = pBgColor
let bgImageCheckBox = UIImageView(image: #imageLiteral(resourceName: "bg_check_box"))
let fgImageCheckBox = UIImageView(image: #imageLiteral(resourceName: "fg_check_box"))
let imageCheckBox = MyCompetenceCheckBoxImageView()
imageCheckBox.setState(niveau: pNumValid)
imageCheckBox.setStateBegin(niveau: pNumValid)
imageCheckBox.updateImage()
let letterObjectif = UILabel()
let textObjectif = UILabel()
letterObjectif.numberOfLines = 0
letterObjectif.text = pLetter
textObjectif.numberOfLines = 0
textObjectif.textAlignment = .left
textObjectif.text = pText
let hSeparator = UIView()
hSeparator.backgroundColor = UIColor.gray
view.addSubview(bgImageCheckBox)
view.addSubview(fgImageCheckBox)
view.addSubview(imageCheckBox)
view.addSubview(letterObjectif)
view.addSubview(textObjectif)
view.addSubview(hSeparator)
bgImageCheckBox.translatesAutoresizingMaskIntoConstraints = false
fgImageCheckBox.translatesAutoresizingMaskIntoConstraints = false
imageCheckBox.translatesAutoresizingMaskIntoConstraints = false
letterObjectif.translatesAutoresizingMaskIntoConstraints = false
textObjectif.translatesAutoresizingMaskIntoConstraints = false
hSeparator.translatesAutoresizingMaskIntoConstraints = false
//bgImageCheckBox Constraint
view.addConstraint(NSLayoutConstraint(item: bgImageCheckBox, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 8))
view.addConstraint(NSLayoutConstraint(item: bgImageCheckBox, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: bgImageCheckBox, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 36))
view.addConstraint(NSLayoutConstraint(item: bgImageCheckBox, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 36))
//fgImageCheckBox Constraint
view.addConstraint(NSLayoutConstraint(item: fgImageCheckBox, attribute: .leading, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .leading, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: fgImageCheckBox, attribute: .trailing, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .trailing , multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: fgImageCheckBox, attribute: .top, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .top, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: fgImageCheckBox, attribute: .bottom, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .bottom, multiplier: 1, constant: 0))
//imageCheckBox Constraint
view.addConstraint(NSLayoutConstraint(item: imageCheckBox, attribute: .leading, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .leading, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: imageCheckBox, attribute: .trailing, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .trailing , multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: imageCheckBox, attribute: .top, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .top, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: imageCheckBox, attribute: .bottom, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .bottom, multiplier: 1, constant: 0))
//hSeparator Constraint
view.addConstraint(NSLayoutConstraint(item: hSeparator, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 1))
view.addConstraint(NSLayoutConstraint(item: hSeparator, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing , multiplier: 1, constant: -8))
view.addConstraint(NSLayoutConstraint(item: hSeparator, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 8))
view.addConstraint(NSLayoutConstraint(item: hSeparator, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0))
//letterObjectif Constraint
view.addConstraint(NSLayoutConstraint(item: letterObjectif, attribute: .leading, relatedBy: .equal, toItem: bgImageCheckBox, attribute: .trailing, multiplier: 1, constant: 4))
//view.addConstraint(NSLayoutConstraint(item: letterObjectif, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute , multiplier: 1, constant: 8))
view.addConstraint(NSLayoutConstraint(item: letterObjectif, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0))
letterObjectif.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000), for: UILayoutConstraintAxis.horizontal)
//textObjectif Constraint
view.addConstraint(NSLayoutConstraint(item: textObjectif, attribute: .leading, relatedBy: .equal, toItem: letterObjectif, attribute: .trailing, multiplier: 1, constant: 4))
view.addConstraint(NSLayoutConstraint(item: textObjectif, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing , multiplier: 1, constant: -8))
view.addConstraint(NSLayoutConstraint(item: textObjectif, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: textObjectif, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0))
textObjectif.setContentHuggingPriority(UILayoutPriority(rawValue: 249), for: UILayoutConstraintAxis.horizontal)
return view
}
}
Je n’arrive pas a réglé ce warning, et je ne sais pas comment tracé correctement et savoir que quelle vue XCode parle :
"<NSLayoutConstraint:0x283f610e0 UIView:0x10473cab0.height == 20 (active)>",
"<NSLayoutConstraint:0x283f58d20 'UISV-fill-proportionally' UIView:0x10473cab0.height == 0 (active)>"
Si quelqu’un a une idée je suis preneur.
Merci d’avance pour vos réponses