Playing with UIStackView

| 4 minutes read

Introduced with iOS 9, UIStackView is very convenient when it comes to display multiple views without managing any of their constraints.

How it works?

var stackViewContainer: UIStackView = UIStackView(frame: CGRect(x: 0.0, y: 0.0, width: stackViewWidth, height: stackViewHeight))
stackViewContainer.axis = .Vertical
stackViewContainer.spacing = 10.0
stackViewContainer.distribution = .FillEqually
stackViewContainer.alignment = .Center

UIStackView parameters :

  • Axis: Vertical or Horizontal
  • Spacing: Margin between subviews
  • Distribution: How the subviews will be displayed within the stack view
  • Alignment: How the subviews will be arranged perpendicularly to the stackview’s axis

And simply add all the subviews in the stack view:

let simpleSubview: UIView = UIView()
stackViewContainer.addArrangedSubview(simpleSubview)

Let’s play

Our playground’s purpose is simple: build a grid of all our friends avatars. The source code is available on github.

Then…

To achieve the same result before the apparition of the stack view, we should have manually created each constraint to align each avatar with its predecessor.
Something like this in VFL :

// Add all avatars for a line
var firstItem: UIView? = nil
for friend:Friend in friendsLine {
   let friendView: FriendView = FriendView(friend: friend)
   friendView.translatesAutoresizingMaskIntoConstraints = false
   lineView.addSubview(friendView)
 
   var hConstraintsArray: [NSLayoutConstraint]?
   if firstItem == nil {
      hConstraintsArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|[friendView]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["friendView": friendView])
   } else {
      // We place the current friend view besides the first item
      hConstraintsArray = NSLayoutConstraint.constraintsWithVisualFormat("H:[firstItem][friendView(==firstItem)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["friendView": iconButton, "firstItem": firstItem!])
   }
 
   let vConstraintsArray:Array = NSLayoutConstraint.constraintsWithVisualFormat("V:|[friendView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["friendView": iconButton])
 
   lineView.addConstraints(hConstraintsArray!)
   lineView.addConstraints(vConstraintsArray)
 
   if firstItem == nil {
      // The width of the first item is equal to the line width divided by the number of avatars displayed in this line
      let multiplierConstraint: NSLayoutConstraint = NSLayoutConstraint(item: lineView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: friendView, attribute: NSLayoutAttribute.Width, multiplier: CGFloat(friendsLine.count), constant: 0.0)
 
      lineView.addConstraint(multiplierConstraint)
   }
 
   firstItem = friendView
}

… And now

Now with UIStackView, if we want to add a view next to an other, as we’ve seen, the code lines are much simpler :

var stackViewLine1: UIStackView = UIStackView()
stackViewLine1.axis = .Horizontal
stackViewLine1.distribution = .FillEqually
stackViewLine1.alignment = .Center
 
for friend in friendsLine {
   let friendStackView: UIStackView = friendView(friend)
   stackViewLine1.addArrangedSubview(friendStackView)
}

In our playground, the main stack view “stackViewContainer” will display lines of friends vertically. Each line is itself a stack view which contains number of avatars displayed horizontally. Finally, each avatar view is indeed a vertical stack view composed with an avatar image view and a name label.

Note: the avatar stack view is only a stack view for test purpose. A simple view would have done the job right. Although it is very simple to build a stack view, too much of a good thing is not good.

More

For Android developers out there, I think you had a laugh reading this. Yes, UIScrollView is similar to LinearLayout.

UIStackView vs LinearLayout

Animations are maybe simpler to use in UIStackView as each property can be animated.

If your application still supports iOS 8 and earlier, projects like OAStackView replicate the behavior of UIStackView for older iOS versions.

We can hope that Apple announces improvements for UIStackView in iOS 10 during the upcoming WWDC 2016.

Share Button

Mélanie Bessagnet Author: Mélanie Bessagnet

Développeuse iOS, experte en pommes.
Ma citation préférée : "Choose a job you love and you will never have to work a day in your life" (Confucius)
Mes hashtags : #iOS #Cocoa #Objective-C #artoys #muffins

Leave a Reply

Required fields are marked *.


CommentLuv badge