What I Want:
I want to place 2 Views
side by side in a horizontal way. For this I am creating UIStackView
programmatically. Look at the below snippet
What I Have Done:
let mStackView = UIStackView()
mStackView.axis = UILayoutConstraintAxis.horizontal
mStackView.distribution = UIStackViewDistribution.fillEqually
mStackView.alignment = UIStackViewAlignment.center
mStackView.spacing = 10
Now inside this I want to put 2 UIView
. Each UIView
will keep center aligned UIImage
and UILabel
. For this I am using another UIStackView
in each UIView
have a look at this snippet.
let mDonationView = UIView()
mDonationView.backgroundColor = UIColor.green
let SV = UIStackView()
SV.axis = UILayoutConstraintAxis.vertical
SV.distribution = UIStackViewDistribution.fill
SV.alignment = UIStackViewAlignment.leading
SV.spacing = 1
SV.alignment = .top
let imageName = "Donate"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 200)
let lbl = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 21))
lbl.text = "Donate"
lbl.textColor = UIColor(hex:AppColor.colorTextPrimary)
lbl.font = lbl.font.withSize(14)
SV.addArrangedSubview(imageView)
SV.addArrangedSubview(lbl)
SV.translatesAutoresizingMaskIntoConstraints = false
mDonationView.addSubview(SV)
and in the end I am adding this back to main UIStackView
namely mStackView
in first code snippet. See below:
mStackView.addArrangedSubview(mDonationView)
similarly I am creating another view and adding in above shown way.
Problem:
UIImageView
and UILabel
are aligned on left where I wanted to be center horizontally and Vertically inside UIView
.UIView
must be equal in width
UIView
are not taking colors
which I have given green to each UIView
In a horizontal stack, this means the first arranged view's leading edge is pinned to the stack's leading edge, and the last arranged view's trailing edge is pinned to the stack's trailing edge. In vertical stacks, the top and bottom edges are pinned to the stack's top and bottom edges, respectively.
A stack view uses this property to define the minimum distance between views within a gravity area and between neighboring views in adjacent gravity areas. The default value for the spacing property is 8. 0 points.
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 subviewsdistribution
controls how the subviews fill the stack view horizontally
For a vertical stack view,
alignment
controls the horizontal alignment of the arranged subviewsdistribution
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
}
}
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