I want to put two buttons with images on left and right edges of the screen, and insert a UITextField
between them. In storyboard
everything is fine, but I need to do it programmatically.
Source:
class SecondViewController: UIViewController {
override func loadView() {
super.loadView()
self.view.backgroundColor = .white
let leftButton = UIButton()
leftButton.setImage(UIImage(named: "first"), for: .normal)
leftButton.setTitle("", for: .normal)
let rightButton = UIButton()
rightButton.setImage(UIImage(named: "second"), for: .normal)
rightButton.setTitle("", for: .normal)
let textField = UITextField()
textField.placeholder = "clear"
textField.borderStyle = .roundedRect
textField.contentHorizontalAlignment = .left
textField.contentVerticalAlignment = .center
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.alignment = .fill
stackView.distribution = .fill
stackView.axis = .horizontal
stackView.spacing = 15
stackView.addArrangedSubview(leftButton)
stackView.addArrangedSubview(textField)
stackView.addArrangedSubview(rightButton)
self.view.addSubview(stackView)
NSLayoutConstraint(item: stackView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1.0, constant: 15).isActive = true
NSLayoutConstraint(item: stackView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1.0, constant: -15).isActive = true
NSLayoutConstraint(item: stackView, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1.0, constant: 50).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
I need a result like on first image.
But at result, I have second.
What did I do wrong ?
You have an elementary constraint ambiguity. You could easily have discovered this just by switching to the View Debugger; you would see three exclamation marks warning you of the problem. The layout engine does not magically know which of the three views should be allowed to stretch horizontally. You have to tell it:
textField.setContentHuggingPriority(UILayoutPriority(249), for: .horizontal)
Set constraints like
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50),
stackView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 15),
stackView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -15),
stackView.heightAnchor.constraint(equalToConstant: 45),
leftButton.widthAnchor.constraint(equalToConstant: 30),
rightButton.widthAnchor.constraint(equalToConstant: 30),
])
Another small change
rightButton.imageView?.contentMode = .scaleAspectFit
leftButton.imageView?.contentMode = .scaleAspectFit
Result
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With