I want to create a chat bottom bar with the following content, in a horizontal UIStackView
:
UITextField
on the left side, taking all the available spaceHere is my code:
let messageTextField = UITextField()
messageTextField.translatesAutoresizingMaskIntoConstraints = false
messageTextField.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "SEND"
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
label.setContentCompressionResistancePriority(.required, for: .horizontal)
label.textColor = .red
let sv = UIStackView()
sv.axis = .horizontal
sv.distribution = .fill
sv.alignment = .center
sv.translatesAutoresizingMaskIntoConstraints = false
// constraint the stack view to the bottomBar view
bottomBar.addSubview(sv)
NSLayoutConstraint.activate([
sv.leadingAnchor.constraint(equalTo: bottomBar.leadingAnchor, constant: 20),
sv.trailingAnchor.constraint(equalTo: bottomBar.trailingAnchor, constant: -20),
sv.bottomAnchor.constraint(equalTo: bottomBar.bottomAnchor, constant: -8),
sv.topAnchor.constraint(equalTo: bottomBar.topAnchor, constant: 8)
])
sv.addArrangedSubview(messageTextField)
sv.addArrangedSubview(label)
NSLayoutConstraint.activate([
messageTextField.heightAnchor.constraint(equalTo:sv.heightAnchor),
// I didn't put any width constraint for textField because it make no sense, as I want it to take all the available space on the right
])
With this code, the label is expanding its size and filling all the available space on the right, and the text field is not showing (inspector says width = 0); exactly the opposite of what I want.
I don't understand why it doesn't work because I explicitly configured it so it does not expand the label with:
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
and instead to expand the text field with:
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
What did I miss here? I have read through many SO answers, Apple documentation, and followed various tutorials and videos, but I'm not able to achieve this seemingly simple thing.
You have it backwards...
Setting Content Hugging Priority
means" control how this element hugs its content.
So, as an example, if you have a UILabel
with only the letter "A" in it, a High content hugging priority will keep the label only as wide as that single letter.
So with these two lines:
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
you've told auto-layout:
keep messageTextField
only as wide as its text, and allow label
to stretch wider than its text
What you want is:
// don't let label stretch at all
label.setContentHuggingPriority(.required, for: .horizontal)
// let message text field stretch if needed
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
The stack view will then stretch the text field to fill the available space.