Couple notes...
First, you'll be better off using auto-layout and constraints (as opposed to explicit frames), particularly with stack views.
Second, UIStackView
properties are probably a little different than what you're thinking...
For a horizontal stack view,
alignment
controls the vertical alignment of the arranged subviews
distribution
controls how the subviews fill the stack view horizontally
For a vertical stack view,
alignment
controls the horizontal alignment of the arranged subviews
distribution
controls how the subviews fill the stack view vertically
I'm assuming this is what you're going for:
Here is the code used to create that (lots of comments, should get you on your way):
class SampleViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let mStackView = UIStackView()
// horizontal stack view
mStackView.axis = .horizontal
// distribution = fillEqually ... means make each arranged subview equal width
mStackView.distribution = .fillEqually
// alignment = center ... means center the arranged subviews vertically
mStackView.alignment = .center
// spacing = 10 ... horizontal gap between arranged subviews
mStackView.spacing = 10
// create the left-side "Donate" view
let donateView = createMyView("Donate", bgColor: UIColor.green, txtColor: UIColor.black)
// create the right-side "Receive" view
let receiveView = createMyView("Receive", bgColor: UIColor.yellow, txtColor: UIColor.blue)
mStackView.addArrangedSubview(donateView)
mStackView.addArrangedSubview(receiveView)
// using auto-layout
mStackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mStackView)
// setup constraints for mStackView
// we'll make it the width of the view, and centered vertically
// allow the height of the donate and receive views to determine the height of the stack view, so
// no bottom or height constraint
NSLayoutConstraint.activate([
mStackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0.0),
mStackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0.0),
mStackView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0),
])
}
func createMyView(_ imageName: String, bgColor: UIColor, txtColor: UIColor) -> UIView {
let myView = UIView()
myView.backgroundColor = bgColor
let vStackView = UIStackView()
// vertical stack view
vStackView.axis = .vertical
// alignment = center ... means the arranged subviews will be centered horizontally
vStackView.alignment = .center
// distribution = fill ... means the arranged subviews will fill the height of the stack view
vStackView.distribution = .fill
// spacing = 1 ... vertical gap between arranged subviews
vStackView.spacing = 1
let vImageName = imageName
let vImageView = UIImageView()
if let vImage = UIImage(named: vImageName) {
vImageView.image = vImage
}
let vLabel = UILabel()
vLabel.text = imageName
vLabel.textColor = txtColor
vLabel.textAlignment = .center
vLabel.font = vLabel.font.withSize(14)
vLabel.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
// add the stack view to myView
myView.addSubview(vStackView)
// add the image view and label as arranged subviews of the stack view
vStackView.addArrangedSubview(vImageView)
vStackView.addArrangedSubview(vLabel)
// we're going to use auto-layout
myView.translatesAutoresizingMaskIntoConstraints = false
vStackView.translatesAutoresizingMaskIntoConstraints = false
vImageView.translatesAutoresizingMaskIntoConstraints = false
vLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// add width and height constraints for the image view
vImageView.widthAnchor.constraint(equalToConstant: 100.0),
vImageView.heightAnchor.constraint(equalToConstant: 200.0),
// constrain the stack view to all four side of myView
vStackView.topAnchor.constraint(equalTo: myView.topAnchor, constant: 0.0),
vStackView.bottomAnchor.constraint(equalTo: myView.bottomAnchor, constant: 0.0),
vStackView.leadingAnchor.constraint(equalTo: myView.leadingAnchor, constant: 0.0),
vStackView.trailingAnchor.constraint(equalTo: myView.trailingAnchor, constant: 0.0),
])
return myView
}
}