ios - Add views in UIStackView programmatically

ID : 20342

viewed : 21

Tags : iosobjective-cios9uistackviewios

Top 5 Answer for ios - Add views in UIStackView programmatically

vote vote

94

Stack views use intrinsic content size, so use layout constraints to define the dimensions of the views.

There is an easy way to add constraints quickly (example):

[view1.heightAnchor constraintEqualToConstant:100].active = true; 

Complete Code:

- (void) setup {      //View 1     UIView *view1 = [[UIView alloc] init];     view1.backgroundColor = [UIColor blueColor];     [view1.heightAnchor constraintEqualToConstant:100].active = true;     [view1.widthAnchor constraintEqualToConstant:120].active = true;       //View 2     UIView *view2 = [[UIView alloc] init];     view2.backgroundColor = [UIColor greenColor];     [view2.heightAnchor constraintEqualToConstant:100].active = true;     [view2.widthAnchor constraintEqualToConstant:70].active = true;      //View 3     UIView *view3 = [[UIView alloc] init];     view3.backgroundColor = [UIColor magentaColor];     [view3.heightAnchor constraintEqualToConstant:100].active = true;     [view3.widthAnchor constraintEqualToConstant:180].active = true;      //Stack View     UIStackView *stackView = [[UIStackView alloc] init];      stackView.axis = UILayoutConstraintAxisVertical;     stackView.distribution = UIStackViewDistributionEqualSpacing;     stackView.alignment = UIStackViewAlignmentCenter;     stackView.spacing = 30;       [stackView addArrangedSubview:view1];     [stackView addArrangedSubview:view2];     [stackView addArrangedSubview:view3];      stackView.translatesAutoresizingMaskIntoConstraints = false;     [self.view addSubview:stackView];       //Layout for Stack View     [stackView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = true;     [stackView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor].active = true; } 

Note: This was tested on iOS 9

UIStackView Equal Spacing (centered)

vote vote

80

Swift 5.0

//Image View let imageView = UIImageView() imageView.backgroundColor = UIColor.blue imageView.heightAnchor.constraint(equalToConstant: 120.0).isActive = true imageView.widthAnchor.constraint(equalToConstant: 120.0).isActive = true imageView.image = UIImage(named: "buttonFollowCheckGreen")  //Text Label let textLabel = UILabel() textLabel.backgroundColor = UIColor.yellow textLabel.widthAnchor.constraint(equalToConstant: self.view.frame.width).isActive = true textLabel.heightAnchor.constraint(equalToConstant: 20.0).isActive = true textLabel.text  = "Hi World" textLabel.textAlignment = .center  //Stack View let stackView   = UIStackView() stackView.axis  = NSLayoutConstraint.Axis.vertical stackView.distribution  = UIStackView.Distribution.equalSpacing stackView.alignment = UIStackView.Alignment.center stackView.spacing   = 16.0  stackView.addArrangedSubview(imageView) stackView.addArrangedSubview(textLabel) stackView.translatesAutoresizingMaskIntoConstraints = false  self.view.addSubview(stackView)  //Constraints stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true 

Based on @user1046037 answer.

vote vote

75

In Swift 4.2

let redView = UIView() redView.backgroundColor = .red  let blueView = UIView() blueView.backgroundColor = .blue  let stackView = UIStackView(arrangedSubviews: [redView, blueView]) stackView.axis = .vertical stackView.distribution = .fillEqually  view.addSubview(stackView)  // stackView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)  // autolayout constraint stackView.translatesAutoresizingMaskIntoConstraints = false  NSLayoutConstraint.activate([     stackView.topAnchor.constraint(equalTo: view.topAnchor),     stackView.leftAnchor.constraint(equalTo: view.leftAnchor),     stackView.rightAnchor.constraint(equalTo: view.rightAnchor),     stackView.heightAnchor.constraint(equalToConstant: 200) ]) 
vote vote

60

UIStackView uses constraints internally to position its arranged subviews. Exactly what constraints are created depends on how the stack view itself is configured. By default, a stack view will create constraints that lay out its arranged subviews in a horizontal line, pinning the leading and trailing views to its own leading and trailing edges. So your code would produce a layout that looks like this:

|[view1][view2]| 

The space that is allocated to each subview is determined by a number of factors including the subview's intrinsic content size and it's compression resistance and content hugging priorities. By default, UIView instances don't define an intrinsic content size. This is something that is generally provided by a subclass, such as UILabel or UIButton.

Since the content compression resistance and content hugging priorities of two new UIView instances will be the same, and neither view provides an intrinsic content size, the layout engine must make its best guess as to what size should be allocated to each view. In your case, it is assigning the first view 100% of the available space, and nothing to the second view.

If you modify your code to use UILabel instances instead, you will get better results:

UILabel *label1 = [UILabel new]; label1.text = @"Label 1"; label1.backgroundColor = [UIColor blueColor];  UILabel *label2 = [UILabel new]; label2.text = @"Label 2"; label2.backgroundColor = [UIColor greenColor];  [self.stack1 addArrangedSubview:label1]; [self.stack1 addArrangedSubview:label2]; 

Note that it is not necessary to explictly create any constraints yourself. This is the main benefit of using UIStackView - it hides the (often ugly) details of constraint management from the developer.

vote vote

60

You have to set you distribution type. In your code, juste add:

self.stack1.distribution = UIStackViewDistributionFillEqually; 

Or you can set the distribution directly in your interface builder. For example:

enter image description here

Hope that helps ;) Lapinou.

Top 3 video Explaining ios - Add views in UIStackView programmatically

Related QUESTION?