This code block tries to get to the heart of the problem. If, after dequeuing a cell (via configure), the constraints are changed so that the cell height is changed, then you end up with a broken constraints warning (Unable to simultaneously satisfy constraints...). However, it displays correctly.
import UIKit
class ViewController: UIViewController {
@IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(Cell.self, forCellReuseIdentifier: "cell")
tableView.estimatedRowHeight = 55.0
tableView.rowHeight = UITableViewAutomaticDimension
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! Cell
cell.configure(array[indexPath.row])
return cell
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
}
}
enum Position {
case Top
case Middle
case Bottom
}
class Cell: UITableViewCell {
private var topConstraint: NSLayoutConstraint!
private var bottomConstraint: NSLayoutConstraint!
private let label = UILabel()
private var previous: Position?
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
label.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.5)
label.textColor = UIColor.blackColor()
label.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(label)
label.leadingAnchor.constraintEqualToAnchor(contentView.leadingAnchor, constant: 30).active = true
label.trailingAnchor.constraintEqualToAnchor(contentView.trailingAnchor, constant: -30).active = true
topConstraint = label.topAnchor.constraintEqualToAnchor(contentView.topAnchor)
topConstraint.active = true
bottomConstraint = label.bottomAnchor.constraintEqualToAnchor(contentView.bottomAnchor)
bottomConstraint.active = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(position: Position) {
if previous != nil {print("previous \(previous!) new \(position)")}
topConstraint.constant = position == .Top ? 30 : 0
bottomConstraint.constant = position == .Bottom ? -30 : 0
label.text = String(position)
previous = position
}
}
let array: [Position] = [.Top, .Middle, .Middle, .Middle, .Bottom,
.Top, .Middle, .Middle, .Middle, .Middle, .Bottom,
.Top, .Middle, .Middle, .Bottom,
.Top, .Middle, .Middle, .Middle, .Middle, .Middle, .Middle, .Bottom,
.Top, .Middle, .Middle, .Middle, .Bottom,
.Top, .Bottom,
.Top, .Middle, .Middle, .Middle, .Middle, .Middle, .Middle, .Bottom,
.Top, .Middle, .Middle, .Middle, .Bottom,
.Top, .Middle, .Middle, .Bottom,
.Top, .Middle, .Middle, .Middle, .Middle, .Middle, .Middle, .Bottom,
]
Error message is...
2016-04-28 22:56:29.831 test-constraint-change[51059:3776208] 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:0x7c117c70 V:|-(30)-[UILabel:0x7c148770'Middle'] (Names: '|':UITableViewCellContentView:0x7c149b70 )>",
"<NSLayoutConstraint:0x7c115bd0 UILabel:0x7c148770'Middle'.bottom == UITableViewCellContentView:0x7c149b70.bottom>",
"<NSLayoutConstraint:0x7c14a3f0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7c149b70(20.5)]>"
)
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x7c115bd0 UILabel:0x7c148770'Middle'.bottom == UITableViewCellContentView:0x7c149b70.bottom>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Set your constraints' priorities to 999. Just like now, it will display correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With