πŸš€ OharaLumina

Add views in UIStackView programmatically

Add views in UIStackView programmatically

πŸ“… | πŸ“‚ Category: Programming

Building dynamic and responsive user interfaces in iOS often involves managing the layout of multiple views efficiently. While Interface Builder offers a visual approach, programmatic UI development provides unparalleled flexibility, especially when dealing with data-driven or highly customizable screens. Among the most powerful tools for this is UIStackView, a layout container that automatically arranges its subviews along an axis, simplifying Auto Layout significantly. Mastering how to add views in UIStackView programmatically is a fundamental skill for any iOS developer aiming for robust, maintainable, and adaptable applications. This guide will walk you through the essential steps and best practices to leverage UIStackView effectively in your Swift projects, ensuring your layouts are both performant and easy to modify.

Understanding UIStackView Fundamentals for Programmatic Use

UIStackView is a non-rendering subclass of UIView that acts as a powerful layout engine. Unlike a regular UIView, it doesn’t draw anything itself; its sole purpose is to manage the layout of its “arranged subviews.” These arranged subviews are laid out either horizontally or vertically, depending on the axis property. This abstraction significantly reduces the need for manually creating and managing complex Auto Layout constraints, making your code cleaner and less prone to layout bugs.

When working with UIStackView programmatically, you gain fine-grained control over its properties and the views it contains. Key properties include axis (vertical or horizontal), alignment (how views are aligned perpendicular to the axis), distribution (how views are sized and spaced along the axis), and spacing (the minimum space between arranged subviews). Leveraging these properties allows you to create highly adaptable interfaces that respond gracefully to device rotations, different screen sizes, and dynamic content changes. For example, a common use case is laying out a series of buttons that need to expand or shrink based on available space, a task made trivial with UIStackView’s distribution options.

The programmatic approach excels when your UI elements are generated dynamically, perhaps from an API response, or when you need to animate views in and out of the layout. Instead of building static scenes in Interface Builder, you can construct and modify your UI directly in code, leading to more flexible and scalable architectures. This method aligns well with modern Swift UI development practices, promoting a clearer separation of concerns and easier testing.

Setting Up Your UIStackView Programmatically

Before you can start adding views, you first need to initialize and configure your UIStackView itself. This involves creating an instance, adding it to a superview, and then defining its position and size using Auto Layout constraints. While UIStackView handles the internal layout of its arranged subviews, you are still responsible for constraining the stack view itself within its parent view.

A typical setup involves instantiating UIStackView, setting its translatesAutoresizingMaskIntoConstraints property to false (critical for programmatic Auto Layout), and then adding it as a subview to your UIViewController’s view or another container view. After adding it, you’ll apply constraints to define its position and dimensions. For instance, you might pin it to the edges of its superview’s safe area, ensuring it adapts correctly to different device layouts and notches.

Here’s a basic example of how to initialize and constrain a vertical stack view to fill its superview’s safe area:

let myStackView = UIStackView() myStackView.axis = .vertical myStackView.alignment = .fill myStackView.distribution = .fillEqually myStackView.spacing = 10 // Important for programmatic Auto Layout myStackView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(myStackView) NSLayoutConstraint.activate([ myStackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), myStackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20), myStackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20), myStackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20) ]) 

This foundational setup is the gateway to effectively manage programmatic UI components within a structured layout. By explicitly defining the stack view’s constraints, you ensure it behaves predictably across various screen sizes and orientations, laying the groundwork for adding and manipulating its content.

How to Add Views in UIStackView Programmatically

Once your UIStackView is set up, the process of adding views to it is remarkably straightforward using the addArrangedSubview(_:) method. This method automatically adds the specified view to the stack view’s arrangedSubviews array and makes it a subview. The stack view then takes over the responsibility of laying out that view according to its axis, alignment, distribution, and spacing properties. It’s crucial to understand that addArrangedSubview(_:) does more than just add a view as a subview; it integrates it into the stack view’s layout management system.

To add multiple views to a UIStackView programmatically, you simply create instances of your desired UIView subclasses (e.g., UILabel, UIButton, UIImageView) and then call addArrangedSubview(_:) for each one. The order in which you add them determines their visual order within the stack view. For example, if you add a label, then a button, then an image view to a vertical stack, they will appear in that top-to-bottom sequence. This allows for dynamic and flexible UI construction without needing to manually define individual constraints between each element.

Here’s a step-by-step Question & Answer :

I’m trying to add views in UIStackView programmatically. For now My code is:

UIView *view1 = [[UIView alloc]init]; view1.backgroundColor = [UIColor blackColor]; [view1 setFrame:CGRectMake(0, 0, 100, 100)]; UIView *view2 = [[UIView alloc]init]; view2.backgroundColor = [UIColor greenColor]; [view2 setFrame:CGRectMake(0, 100, 100, 100)]; [self.stack1 addArrangedSubview:view1]; [self.stack1 addArrangedSubview:view2]; 

When i deploy the app, there is only 1 view and it is with black colour.(view1 get the parameters for view2 too)

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)