iosswiftuistackviewsnapkit

How to programmatically align elements in a Stackview using SnapKit?


I'm trying to achieve a specific design inside a custom reusable view.

(Something like this: )

enter image description here

So I pass an URL to retrive the image and I pass a String to add below.

Firstly, I want the entire view to be the width of the elements (if the text is long then the entire view will be wider), I don't know how to do that, the view seems to be the entire width of the screen.

Secondly, I want the items to be centered horizontally and vertically, what I tried does not work.

Here is my current code :

func initLayout() {
        stackView.axis  = NSLayoutConstraint.Axis.vertical
        stackView.distribution  = UIStackView.Distribution.fillEqually
        stackView.alignment = UIStackView.Alignment.center
        stackView.spacing   = 10.0

        stackView.addArrangedSubview(imageView)
        stackView.addArrangedSubview(textContainer)
        stackView.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(stackView)
        self.snp.makeConstraints { (make) -> Void in
            make.height.equalTo(70)
        }
        self.stackView.snp.makeConstraints{ (make) -> Void in
            make.edges.equalTo(self)
        }
    }

And it results in something like this: enter image description here

As you can (or cannot) see, the view is centered in the middle of the screen, which is not what I want. The view should be the width of the text and everything centered inside this particular width, then I add it inside my VC and place it so it's leading.


Solution

  • if I understand well the is your constraint without Snapkit:

    Set your objects under your class controller declaration:

    let myImageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleToFill
        iv.clipsToBounds = true
        iv.backgroundColor = .red
        iv.translatesAutoresizingMaskIntoConstraints = false
        
        return iv
    }()
    
    let myLabel: UILabel = {
        let label = UILabel()
        label.text = "Débats"
        label.textColor = .white
        label.textAlignment = .center
        label.font = .systemFont(ofSize: 30, weight: .semibold) // set your font size here
        label.translatesAutoresizingMaskIntoConstraints = false
        
        return label
    }()
    

    Now in viewDidLoad set parameters and constraints:

    myImageView.image = UIImage(named: "profilo") // set here your image
        
        let myWidth = myLabel.intrinsicContentSize.width // This reveal only text width in label
        
        view.addSubview(myLabel)
        myLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5).isActive = true
        myLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true
        myLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 25).isActive = true
        myLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        view.addSubview(myImageView)
        myImageView.widthAnchor.constraint(equalToConstant: myWidth).isActive = true
        myImageView.heightAnchor.constraint(equalTo: myImageView.widthAnchor).isActive = true
        myImageView.bottomAnchor.constraint(equalTo: myLabel.topAnchor).isActive = true
        myImageView.centerXAnchor.constraint(equalTo: myLabel.centerXAnchor).isActive = true
    

    This is the result:

    enter image description here

    Intere code:

    class Aiutotipo: UIViewController {
    
    let myImageView: UIImageView = {
        
        let iv = UIImageView()
        iv.contentMode = .scaleToFill
        iv.clipsToBounds = true
        iv.backgroundColor = .red
        iv.translatesAutoresizingMaskIntoConstraints = false
        
        return iv
    }()
    
    let myLabel: UILabel = {
        let label = UILabel()
        label.text = "Débats"
        label.textColor = .white
        label.textAlignment = .center
        label.font = .systemFont(ofSize: 30, weight: .semibold)
        label.translatesAutoresizingMaskIntoConstraints = false
        
        return label
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        myImageView.image = UIImage(named: "profilo") // set here your image
        
        let myWidth = myLabel.intrinsicContentSize.width // This reveal only text width in label
        
        view.addSubview(myLabel)
        myLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5).isActive = true
        myLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true
        myLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 25).isActive = true
        myLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        view.addSubview(myImageView)
        myImageView.widthAnchor.constraint(equalToConstant: myWidth).isActive = true
        myImageView.heightAnchor.constraint(equalTo: myImageView.widthAnchor).isActive = true
        myImageView.bottomAnchor.constraint(equalTo: myLabel.topAnchor).isActive = true
        myImageView.centerXAnchor.constraint(equalTo: myLabel.centerXAnchor).isActive = true
     }
    }