I'm going to make a numPad using stackView this is my code
private func setKeypadButton(num: Int) -> UIButton {
let button = UIButton()
button.setTitle(String(num), for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 50)
button.setTitleColor(.black, for: .normal)
button.frame.size = CGSize(width: 60, height: 60)
button.tapPublisher
.sink {
guard let num = button.titleLabel?.text else { return }
print(num)
}.store(in: &subscription)
return button
}
private func setKeypad() {
let keypadHorizontalStackView = UIStackView()
keypadHorizontalStackView.axis = .horizontal
keypadHorizontalStackView.spacing = 0
for i in 1...9 {
let button = setKeypadButton(num: i)
keypadHorizontalStackView.addArrangedSubview(button)
if i % 3 == 0 {
keypadVerticalStackView.addArrangedSubview(keypadHorizontalStackView)
keypadHorizontalStackView.arrangedSubviews.forEach {
keypadHorizontalStackView.removeArrangedSubview($0)
}
}
}
}
SetKeypad function is executed in viewDidLoad I expect the view to come out like this
123
456
789
But my buttons overlap in the z-direction
What am I missing?
CodePudding user response:
First this method .removeArrangedSubview
doesn't remove provided view from stack's subview array, therefore the view is still display as a part of view hierarchy, that why you see your button overlap in z-direction. You should use view.removeFromSuperview
if you want to remove view from superview. You can read about removeArrangedSubview here
Second stackView is a class, so it's reference type. So this line keypadVerticalStackView.addArrangedSubview(keypadHorizontalStackView)
just add the same horizontal stack view to your vertical stack view and its not correct solution.
If I want to make UI display as your expectation, i will do something like
let horizontalStackViews = [UIStackView(), UIStackView(), UIStackView()]
horizontalStackViews.forEach { (stackView) in
stackView.axis = .horizontal
stackView.spacing = 0
stackView.distribution = .equalSpacing
verticalStackView.addArrangedSubview(stackView)
}
var row = 0
var number = 1
repeat {
horizontalStackViews[row].addArrangedSubview(setKeypadButton(num: number))
number = 1
if number % 3 == 1 { row = 1 }
} while row < 3
CodePudding user response:
UIStackView is a reference type Therefore, when removingArrangedSubView, the views in the verticalStackView are also removed
So I changed it like this, and it works fine
private func setKeypad() {
var count = 1
for _ in 0..<3 {
let keypadHorizontalStackView = UIStackView()
keypadHorizontalStackView.axis = .horizontal
keypadHorizontalStackView.spacing = 0
keypadHorizontalStackView.distribution = .fillEqually
for _ in 0..<3 {
let button = setKeypadButton(num: count)
keypadHorizontalStackView.addArrangedSubview(button)
count = 1
}
keypadVerticalStackView.addArrangedSubview(keypadHorizontalStackView)
}
}