I am trying to implement passcode screen, but I am having trouble with alignment, as you can see in this picture.
What I’m trying to do is, have three buttons in each row, so it actually looks like a "keypad". I am not quite sure how could I do this. I thought about making inside of first stack view which is vertical, four others horizontal stack views, but couldn’t manage to do it. Any suggestion or help would be appreciated. Thanks 🙂
Code is below.
class ViewController: UIViewController {
var verticalStackView: UIStackView = {
var verticalStackView = UIStackView()
verticalStackView.translatesAutoresizingMaskIntoConstraints = false
verticalStackView.axis = .vertical
verticalStackView.distribution = .fillEqually
verticalStackView.spacing = 13
verticalStackView.alignment = .fill
verticalStackView.contentMode = .scaleToFill
verticalStackView.backgroundColor = .red
return verticalStackView
}()
var horizontalStackView: UIStackView = {
var buttons = [PasscodeButtons]()
var horizontalStackView = UIStackView(arrangedSubviews: buttons)
horizontalStackView.translatesAutoresizingMaskIntoConstraints = false
horizontalStackView.axis = .horizontal
horizontalStackView.distribution = .fillEqually
horizontalStackView.alignment = .fill
horizontalStackView.spacing = 25
horizontalStackView.contentMode = .scaleToFill
horizontalStackView.backgroundColor = .green
return horizontalStackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
configureStackView()
configureConstraints()
}
func configureStackView() {
view.addSubview(verticalStackView)
verticalStackView.addSubview(horizontalStackView)
addButtonsToStackView()
}
func addButtonsToStackView() {
let numberOfButtons = 9
for i in 0...numberOfButtons {
let button = PasscodeButtons()
button.setTitle("(i)", for: .normal)
button.tag = i
horizontalStackView.addArrangedSubview(button)
}
}
func configureConstraints() {
verticalStackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
verticalStackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 50).isActive = true
verticalStackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -50).isActive = true
verticalStackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -100).isActive = true
horizontalStackView.topAnchor.constraint(equalTo: verticalStackView.topAnchor, constant: 10).isActive = true
horizontalStackView.leadingAnchor.constraint(equalTo: verticalStackView.leadingAnchor, constant: 10).isActive = true
}
}
In case PasscodeButtons matters, here is code from there too.
class PasscodeButtons: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
setupButton()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupButton()
}
override func awakeFromNib() {
super.awakeFromNib()
setupButton()
}
private func setupButton() {
setTitleColor(UIColor.black, for: .normal)
setTitleColor(UIColor.black, for: .highlighted)
}
private func updateView() {
layer.cornerRadius = frame.width / 2
layer.masksToBounds = true
layer.borderColor = UIColor(red: 0/255.0, green: 0/255.0, blue: 0, alpha:1).cgColor
layer.borderWidth = 2.0
}
override func layoutSubviews() {
super.layoutSubviews()
updateView()
backgroundColor = .cyan
}
}
2
Answers
follow the steps:-
The general idea is:
.fillEqually
Then, to generate everything, create an array of arrays of Ints for the key numbers, laid out like a keypad:
Loop through, creating each row of buttons.
Here’s a quick example (I modified your PasscodeButton class slightly):
Output:
You’ll likely want to play with the sizing, but that should get you on your way.
Edit – comment "I would like for 0 to stay in last row in the middle, and on the left side I would pop in touch id icon and on the right backspace button, how could I leave last row out of a shuffle?"
When you create your "grid" of buttons:
Change the
keyNums
array to:Here’s some updated code, using a "KeyPad"
UIView
subclass:and here’s how it looks, setting the keypad view width to
240
and the button spacing to12
: