I'm trying to create these 6 UITextField centered within a UIVIew that I have centered and is 0.85 the width of self.view
. I was able to get it working on one iPhone size however it was hardcoded and doesn't transform well on other iPhone sizes.
So now I'm trying to figure out the best way to properly center these 6 elements.
Here's what I currently have:
class FormView: UIViewController {
//INSTANTIATING VARIABLES
...
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
setupCodeFieldView()
}
private func setupCodeFieldView(){
codeFieldView.backgroundColor = .green
codeFieldView.translatesAutoresizingMaskIntoConstraints = false
parentSubview.addSubview(codeFieldView)
codeFieldView.heightAnchor.constraint(equalToConstant: 60).isActive = true
codeFieldView.topAnchor.constraint(equalTo: parentSubview.bottomAnchor, constant: 5).isActive = true
//SETTING WIDTH SIZE AND CENTERING PARENT VIEW
codeFieldView.widthAnchor.constraint(equalTo:view.widthAnchor, multiplier: 0.85).isActive = true
codeFieldView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
setupCodeFields()
}
fileprivate func setupCodeFields() {
var textFieldArr: [UITextField] = []
for index in 0...5{
let field: UITextField = UITextField()
field.returnKeyType = .next
field.setUnderline()
field.borderStyle = .none
field.keyboardType = .numberPad
field.backgroundColor = UIColor.white
field.tag = index
field.textAlignment = .center
let valueWidth = codeFieldView.bounds.size.width/6
field.placeholder = String(describing: valueWidth)
field.accessibilityIdentifier = "field" + String(index)
codeFieldView.addSubview(field)
field.layer.cornerRadius = 5.0
field.layer.borderWidth = 1.0
field.layer.borderColor = UIColor(red: 0.45, green: 0.46, blue: 0.50, alpha: 1.00).cgColor
field.translatesAutoresizingMaskIntoConstraints = false
//HERE IS HOW SET THE WIDTH OF THE BUTTON
field.widthAnchor.constraint(equalToConstant: floor(valueWidth)-5).isActive = true
field.heightAnchor.constraint(equalToConstant: 60).isActive = true
field.topAnchor.constraint(equalTo: codeFieldView.topAnchor).isActive = true
if index == 0 {
field.leftAnchor.constraint(equalTo:codeFieldView.leftAnchor).isActive = true
} else {
field.leftAnchor.constraint(equalTo: textFieldArr[index-1].rightAnchor, constant: 5).isActive = true
}
textFieldArr.append(field)
}
}
}
Here's what I currently have. You can see that the 6 elements' parent view is centered and that I'm struggling to have the 6 children UITextFields perfectly spaced across the highlighted green parent view.
You can do this easily with a UIStackView
Here's a quick example (based on your code):
class FormView: UIViewController {
//INSTANTIATING VARIABLES
//...
let codeFieldView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .gray
setupCodeFieldView()
}
private func setupCodeFieldView() {
codeFieldView.backgroundColor = .green
codeFieldView.translatesAutoresizingMaskIntoConstraints = false
// not clear what you're doing with "parentSubview"
// so let's just add it to the root view
view.addSubview(codeFieldView)
// always respect safe-area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// height of 60
codeFieldView.heightAnchor.constraint(equalToConstant: 60),
// 85% of the width
codeFieldView.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.85),
// centered vertically and horizontally
codeFieldView.centerYAnchor.constraint(equalTo: g.centerYAnchor),
codeFieldView.centerXAnchor.constraint(equalTo: g.centerXAnchor),
])
setupCodeFields()
}
fileprivate func setupCodeFields() {
// let's add a stack view to codeFieldView
let stackView = UIStackView()
stackView.spacing = 5
stackView.distribution = .fillEqually
stackView.translatesAutoresizingMaskIntoConstraints = false
codeFieldView.addSubview(stackView)
NSLayoutConstraint.activate([
// constrain stack view to all 4 sides of code field view
stackView.topAnchor.constraint(equalTo: codeFieldView.topAnchor),
stackView.leadingAnchor.constraint(equalTo: codeFieldView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: codeFieldView.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: codeFieldView.bottomAnchor),
])
// now we add the text fields
for index in 0...5 {
let field: UITextField = UITextField()
field.returnKeyType = .next
//field.setUnderline()
field.borderStyle = .none
field.keyboardType = .numberPad
field.backgroundColor = UIColor.white
field.tag = index
field.textAlignment = .center
field.accessibilityIdentifier = "field" + String(index)
field.layer.cornerRadius = 5.0
field.layer.borderWidth = 1.0
field.layer.borderColor = UIColor(red: 0.45, green: 0.46, blue: 0.50, alpha: 1.00).cgColor
// add it to the stack view
stackView.addArrangedSubview(field)
}
}
}
The result:
Your question didn't indicate how you want the UI to look on a wider device, so here's how that looks when the phone is rotated: