2

Came form android background now trying to understand UIStackView in ios with simple login view example but got confused from distorted output. Following are my details:

My Login view file:

import UIKit
import SnapKit

class LoginView: UIView {

    let loginStackView = UIStackView();

    let emailStackView = UIStackView()
    let emailImageView = UIImageView()
    let emailTextView = UITextView();

    let passStackView = UIStackView()
    let passImageView = UIImageView()
    let passTextView = UITextView();

    let loginButton = UIButton();
    let loginButton2 = UIButton();

    override init(frame: CGRect) {
        super.init(frame: frame)
        loadUI();
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    private func loadUI(){

        self.addSubview(loginStackView);

        emailStackView.axis = .horizontal
        emailStackView.distribution = .equalSpacing
        emailStackView.translatesAutoresizingMaskIntoConstraints = false
        emailStackView.addArrangedSubview(emailImageView);
        emailStackView.addArrangedSubview(emailTextView);

        passStackView.axis = .horizontal
        passStackView.distribution = .equalSpacing
        passStackView.translatesAutoresizingMaskIntoConstraints = false
        passStackView.addArrangedSubview(passImageView);
        passStackView.addArrangedSubview(passTextView);

        loginStackView.axis = .vertical
        loginStackView.distribution = .fill
        loginStackView.alignment = .fill
        loginStackView.spacing = 10
        loginStackView.translatesAutoresizingMaskIntoConstraints = false
        loginStackView.addArrangedSubview(emailStackView);
        loginStackView.addArrangedSubview(loginButton);
        loginStackView.addArrangedSubview(passStackView);
        loginStackView.addArrangedSubview(loginButton2);
        loginStackView.snp.makeConstraints{(make) -> Void in
            make.center.equalToSuperview();
        }

        emailImageView.image = UIImage(named: "sample");
        emailImageView.snp.makeConstraints{(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(50)
        }

        emailTextView.snp.makeConstraints{(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(200)
        }


        passImageView.image = UIImage(named: "sample2");
        passImageView.snp.makeConstraints{(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(50)
        }


        passTextView.snp.makeConstraints{(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(200)
        }

        loginButton.setTitle("Login", for: .normal);
        loginButton.snp.makeConstraints{ (make) in
            make.height.equalTo(50)
            make.width.equalTo(250)
        }

        loginButton2.setTitle("Login2", for: .normal);
        loginButton2.snp.makeConstraints{ (make) in
            make.height.equalTo(50)
            make.width.equalTo(250)
        }


    }

}

Then I used this class in login view controller like this:

let superview = self.view;

let loginView = LoginView();
superview?.addSubview(loginView);
superview?.backgroundColor = UIColor.lightGray;
loginView.backgroundColor = UIColor.red;

loginView.snp.makeConstraints{(make) -> Void in
make.height.equalTo(superview!);
make.width.equalTo(superview!);
}

for above code my output is this:

enter image description here

My queries:

  1. Why views before passStackView are not showing?
  2. Why loginView not taking full screen(that constrained on loginStackView suppose to put loginStackView in the middle of loginView)

This is happening with nested stack views only if a use single stack everything works fine. Please let me know what I am missing here.

This is what I am expecting:

enter image description here

Pushpendra
  • 2,791
  • 4
  • 26
  • 49
  • did you try to `self.addSubview(loginStackView)` after all modifications? – Sandu Oct 12 '17 at 13:21
  • try setting some more constraints like in [here](https://useyourloaf.com/blog/pain-free-constraints-with-layout-anchors/) – Sandu Oct 12 '17 at 13:27

1 Answers1

3

You really only missed two settings:

    loginView.snp.makeConstraints{(make) -> Void in
        make.height.equalTo(superview!);
        make.width.equalTo(superview!);

        // you also need to set position,
        // this will center the view
        make.centerX.equalTo(superview!);
        make.centerY.equalTo(superview!);
    }

Note that you also have a "built-in" superview method, so it could be written like this:

    loginView.snp.makeConstraints{(make) -> Void in
        make.width.equalToSuperview()
        make.height.equalToSuperview()
        make.centerX.equalToSuperview()
        make.centerY.equalToSuperview()
    }

A strong recommendation for you though... I know that many people use SnapKit for convenience, you may find a lot of value in learning how auto-layout and constraints work. Just understanding the basics of it can help out tremendously when you come across a situation like this.

For what it's worth, anyway.

DonMag
  • 69,424
  • 5
  • 50
  • 86
  • This is it, I thought just making width and height equals to superview would take the entire screen because it worked for single stackview. I will take serious note of your recommendation for auto-layouts. Thanks – Pushpendra Oct 12 '17 at 14:17