I am using the following to add a UITextField to a UIStackView. The main issue is the UITextField is expanding to take the complete height. What am I doing wrong? I want UITextField to be of 44 or 60 points height.
lazy var nameTextField: UITextField = {
let textfield = UITextField()
textfield.translatesAutoresizingMaskIntoConstraints = false
textfield.placeholder = "Budget name"
textfield.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 0))
textfield.leftViewMode = .always
textfield.borderStyle = .roundedRect
return textfield
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.green
setupUI()
}
private func setupUI() {
let stackView = UIStackView()
stackView.alignment = .leading
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = UIStackView.spacingUseSystem
stackView.isLayoutMarginsRelativeArrangement = true
stackView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20)
view.addSubview(stackView)
stackView.addArrangedSubview(nameTextField)
// add constraints on nameTextField
nameTextField.widthAnchor.constraint(equalToConstant: 200).isActive = true
nameTextField.heightAnchor.constraint(equalToConstant: 60).isActive = true
// add constraints stackview
stackView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
}
}
CodePudding user response:
A UIStackView
arranges its subviews (.addArrangedSubview()
).
So, you are telling auto-layout to:
- make the text field 60-points tall
- AND
- make the text field as tall as the stack view
In this case, the stack view wins.
Edit - for clarification...
When you ran your app, you should have seen a bunch of auto-layout error / warning messages. That tells you that you have assigned conflicting constraints.
If you want the text field height to use the .heightAnchor.constraint(equalToConstant: 60)
that you've assigned, you have a few options...
1 - Don't embed it in a stack view.
2 - Don't assign a height to the stack view (either directly or with top & bottom constraints).
3 - add additional arrangedSubviews
to the stack view.
So, if you make only this change to your code:
stackView.addArrangedSubview(nameTextField)
// comment out this line
//stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
you'll get this:
If you leave that line in, and add a yellow-background UILabel
as another arranged subview:
stackView.addArrangedSubview(nameTextField)
// leave this un-commented
stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
let label = UILabel()
label.text = "The Label"
label.backgroundColor = .yellow
label.widthAnchor.constraint(equalToConstant: 200).isActive = true
stackView.addArrangedSubview(label)
you'll get this:
because you gave the text field an explicit Height constraint, so the label height "stretches."
Or, if you add the label and omit the stack view's bottom anchor:
stackView.addArrangedSubview(nameTextField)
// comment out this line
//stackView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
let label = UILabel()
label.text = "The Label"
label.backgroundColor = .yellow
label.widthAnchor.constraint(equalToConstant: 200).isActive = true
stackView.addArrangedSubview(label)
you'll get this:
because you gave the text field an explicit Height constraint, and let the label use its Intrinsic Content Size
.