So I have a 2 depth table view with sections and rows. When I expand the table view for the first time, everything's already good, but if I expand it for the 2nd, 3rd, .... times or scrolling when the sections expanded, then the left constraint for the rows sections is broken, for more details please see the image below:
It's my 3rd time I expanding the sections. And as you can see there're 2 rows that have broken left constraint. Here's my code:
func configureCell(data: FirstDepth) {
self.firstDepthData = data
self.firstDepthLabel.text = data.name
self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 20)
}
func configureSecondCell(data: SecondDepth) {
self.secondDepthData = data
self.firstDepthLabel.text = data.name
self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 50)
}
So the table view will call configureCell for the sections, and configureSecondCell for the rows, I've read maybe this is because of re-initialize the constraints, but how to only update the constant?
If needed, here's my code for the table view cell:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CellFirstDepth.id, for: indexPath) as! CellFirstDepth
if let firstDepthData = self.firstDepthData {
if indexPath.row == 0 {
// Call Cell for sections
cell.configureCell(data: firstDepthData[indexPath.section])
} else {
// Call Cell for rows
cell.configureSecondCell(data: firstDepthData[indexPath.section].child[indexPath.row - 1])
}
}
return cell
}
And this is my centerY function, just a code to make the element center to Y axis, and add anchor to left/right:
func centerY(inView view: UIView, leftAnchor: NSLayoutXAxisAnchor? = nil, rightAnchor: NSLayoutXAxisAnchor? = nil, paddingLeft: CGFloat? = nil, paddingRight: CGFloat? = nil, constant: CGFloat? = 0) {
translatesAutoresizingMaskIntoConstraints = false
centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: constant!).isActive = true
if let leftAnchor = leftAnchor, let paddingLeft = paddingLeft {
self.leftAnchor.constraint(equalTo: leftAnchor, constant: paddingLeft).isActive = true
} else if let rightAnchor = rightAnchor, let paddingRight = paddingRight {
self.rightAnchor.constraint(equalTo: rightAnchor, constant: -paddingRight).isActive = true
}
}
CodePudding user response:
You haven't shown us what your .centerY(...)
function does, but pretty safe guess as to the problem.
It looks like you are adding a .leftAnchor
constraint with a constant of 20
, and then the cell get's reused and you're adding another .leftAnchor
constraint with a constant of 50
.
You need to edit your cell code to use a single constraint, and update its .constant
property, instead of adding multiple constraints.
Edit
With a little searching, you can find many complete examples, but here's the general idea.
In your cell class, add this var property:
var labelLeftConstraint: NSLayoutConstraint!
Then, in your cell class initialization, create that constraint:
labelLeftConstraint = self.firstDepthLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0)
labelLeftConstraint.isActive = true
And, change your configure
funcs like this:
func configureCell(data: FirstDepth) {
self.firstDepthData = data
self.firstDepthLabel.text = data.name
labelLeftConstraint.constant = 20
//self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 20)
}
func configureSecondCell(data: SecondDepth) {
self.secondDepthData = data
self.firstDepthLabel.text = data.name
labelLeftConstraint.constant = 50
//self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 50)
}
Now you will have only a single constraint, and your code will be setting its .constant
instead of creating it over and over (which is what causes the problem).