Reputation: 31283
I have a custom UITableViewCell
layout that looks like this. It has three labels.
Label 2 is an optional one. It's not present in every cell. So I want to hide that and move the Label 1 down a little to be center aligned with the Label 3 when that happens.
Here are the constraints I've added for each label.
Label 1
Label 2
Label 3
Notice I have added an extra constraint, Align center to Y with the value of 0 to Label 1 and have set its priority to 750. I figured if I remove the Label 2, that constraint with the lower priority will take its place and move down.
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
if indexPath.row == 1 {
cell.label2.removeFromSuperview()
cell.updateConstraints()
}
return cell
}
}
But it doesn't seem to work. Label 2 is removed but Label 1's position is still the same.
How can I accomplish what I'm after?
Attempt #1
As per Mr. T's answer below, I added a top constraint to the Label 1. And then in the cellForRowAtIndexPath
method, I changed it's value.
override func tableView(tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
if indexPath.row == 1 {
cell.label2.removeFromSuperview()
cell.topConstraint.constant = cell.bounds.height / 2
cell.layoutIfNeeded()
}
return cell
}
But this didn't work either.
Upvotes: 3
Views: 1606
Reputation: 31283
I figured out a way to do this utilizing the new active
property of NSLayoutConstraint
s as described in this answer.
I made an IBOutlet
to the Align center Y constraint with the value -13. Removed the weak
keyword from it.
Then in the cellForRowAtIndexPath
method, I'm simply toggling the value for the active
property.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
if indexPath.row % 2 == 0 {
cell.label2.hidden = true
cell.oldConstraint.active = false
} else {
cell.label2.hidden = false
cell.oldConstraint.active = true
}
return cell
}
Upvotes: 0
Reputation: 20379
I am pretty much impressed the way you came so far as that would have been exactly the same steps i would have followed if i had to accomplish it :)
Now my suggestion: remove an extra "Align center to Y with the value of 0 to Label 1" that you have added that is not serving any purpose :)
I can see you already have a align center to y with some offset i believe -13 to label 1. Create an iboutlet for that :) let's say its name as centerLabel1Constraint :)
whenever you want to bring label 1 to center hide label 2 and set centerLabel1Constraint.constant = 0 and call [cell layoutIfNeeded]
That should do the job :) Happy coding :)
Upvotes: 0
Reputation: 11201
Try to have an outlet for the top constraint for the label 1. And when you remove the label 2, update the top constraint for the label1 which is the container.height/2 Or Remove the top constraint and give the centerY constraint to the label 1. And do layout if needed, once you updated the constraints.
Upvotes: 0