Reputation: 1404
I have 2 simple UILabel that needs to be placed horizontally. One of them on right side of view, while second one is on the left side and gets all possible space. Here is my constraints:
amountOfQuestions.rightAnchor.constraint(equalTo: rightAnchor, constant: -8).isActive = true
amountOfQuestions.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
topicName.leftAnchor.constraint(equalTo: leftAnchor, constant: 8).isActive = true
topicName.topAnchor.constraint(equalTo: topAnchor, constant: 8).isActive = true
topicName.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8).isActive = true
topicName.rightAnchor.constraint(equalTo: amountOfQuestions.leftAnchor, constant: -8).isActive = true
Seems like everything is ok, but when table view is shown, it looks like this:
But after I scroll couple of times my table up and down, it became normal:
Why my table is not shown immediately like in second picture?
Solution:
amountOfQuestions.rightAnchor.constraint(equalTo: rightAnchor, constant: -8).isActive = true
amountOfQuestions.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
amountOfQuestions.setContentHuggingPriority(.required, for: .horizontal)
amountOfQuestions.setContentCompressionResistancePriority(.required, for: .horizontal)
topicName.leftAnchor.constraint(equalTo: leftAnchor, constant: 8).isActive = true
topicName.topAnchor.constraint(equalTo: topAnchor, constant: 8).isActive = true
topicName.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8).isActive = true
topicName.rightAnchor.constraint(equalTo: amountOfQuestions.leftAnchor, constant: -8).isActive = true
topicName.setContentHuggingPriority(.required, for: .horizontal)
topicName.setContentCompressionResistancePriority(.required, for: .vertical)
let myBottom = topicName.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8)
myBottom.priority = UILayoutPriority(rawValue: UILayoutPriority.required.rawValue - 1)
myBottom.isActive = true
Upvotes: 0
Views: 518
Reputation: 130122
There are multiple problems that can affect the layout and make it incorrectly defined:
Never constrain content to the cell itself. Always constrain to the contentView
of the cell, e.g.:
amountOfQuestions.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -8).isActive = true
(make sure you are adding the labels as subviews of the contentView
, not of the cell itself).
If you want the size of the labels to have any effect, you need to set hugging and compression resistance priorities correctly. Otherwise the layout does not have to respect the content:
// you want topic name to resize vertically to respect the content
topicName.setHuggingPriority(.required, for: .vertical)
topicName.setContentCompressionResistancePriority(.required, for: .vertical)
// you want amount of question to resize horizontally to respect the content
amountOfQuestions.setHuggingPriority(.required, for: .horizontal)
amountOfQuestions.setContentCompressionResistancePriority(.required, for: .horizontal)
To avoid layout conflicts during the first layout, it's a good idea to give one the of the vertical constraints a slightly lower layout priority:
let bottomAnchor = topicName.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8)
bottomAnchor.priority = UILayoutPriority(rawValue: UILayoutPriority.required.rawValue - 1)
bottomAnchor.isActive = true
Upvotes: 2
Reputation: 100533
1- UILabels have an intrinsic content value , that means you don't have to specify a width / height for them , so when you place them horizontally like this
| - lbl1 - lbl2 - |
This causes a constraint ambiguity because autolayout need to know which label to trim when a one content is too bigger that's why you need to set horizontal compression resistance && setHuggingPriority to lbl2 = 1000
2- You need to lower priority of bottom constraint as the cell assumes a fixed height in the begining of layout and that height may conflict with current total height of the vertical content , so you lower it to avoid this conflict
Upvotes: 1