Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a Horizontal Stackview with 2 UiView Inside

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:

  1. My problem is I can see 2 views side by side, but in that the UIImageView and UILabel are aligned on left where I wanted to be center horizontally and Vertically inside UIView.
  2. Both UIView must be equal in width
  3. UIView are not taking colors which I have given green to each UIView
like image 546
A.s.ALI Avatar asked Feb 25 '19 11:02

A.s.ALI


People also ask

What is horizontal stack view in Swift?

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.

What is stackView spacing?

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.


Video Answer


1 Answers

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:

enter image description here

enter image description here

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

    }

}
like image 157
DonMag Avatar answered Sep 23 '22 21:09

DonMag