Working with the iOS 10 Stack View Class

From Techotopia
Revision as of 18:03, 3 November 2016 by Neil (Talk | contribs)

Jump to: navigation, search

PreviousTable of ContentsNext
Implementing iOS 10 TableView Navigation using Storyboards in Xcode 8An iOS 10 Stack View Tutorial


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book


With hindsight it seems hard to believe, but until the introduction of iOS 9 there was no easy way to build stack based user interface layouts that would adapt automatically to different screen sizes and changes in device orientation. While such results could eventually be achieved with careful use of size classes and Auto Layout this was far from a simple task. That changed with the introduction of the UIStackView class in the iOS 9 SDK.


Contents


Introducing the UIStackView Class

The UIStackView class is a user interface element that allows subviews to be arranged linearly in either a column or row orientation. The class makes extensive use of Auto Layout and automatically sets up many of the Auto Layout constraints needed to provide the required layout behavior. The class goes beyond simple stacking of views, allowing additional Auto Layout constraints to be added to subviews, and providing a range of properties that enable the layout behavior of those subviews to be modified to meet different requirements.

The UIStackView object is available for inclusion with Storyboard scenes simply by dragging and dropping either the Horizontal Stack View or Vertical Stack View from the Object Library onto the scene canvas. Once added to a scene, subviews are added simply by dragging and dropping the required views onto the stack view.

Existing views in a storyboard scene may be wrapped in a stack view simply by Shift-clicking on the views so that they are all selected before clicking on the Stack button located in the bottom of the Interface Builder panel as highlighted in Figure 31-1. Interface Builder will decide whether to encapsulate the selected views into a horizontal or vertical stack depending on the layout positions of the views:


Xcode 7 stack button.png

Figure 31-1


By default the stack view will resize to accommodate the subviews as they are added. As with any other view type, however, Auto Layout constraints may be used to constrain and influence the resize behavior of the stack view in relation to the containing view and any the other views in the scene layout.

Once added to a storyboard scene, a range of properties are available within the Attributes Inspector to customize the layout behavior of the object.

Stack views may be used to create simple column or row based layouts, or nested within each other to create more complex layouts. Figure 31-2, for example, shows an example layout consisting of a vertical stack view containing 3 horizontal stack views each containing a variety of subviews:


Ios9 stack views nested.png

Figure 31-2


UIStackView class instances may also be created and managed from within the code of an iOS 9 app. Stack view instances can be created in code and initialized with an array of subviews. Views may also be inserted and removed dynamically from within code and the attributes of the stack view changed via a range of properties. The subviews of a stack view object are held in an array which can be accessed via the arrangedSubviews property of the stack view instance.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Understanding Subviews and Arranged Subviews

The UIStackView class contains a property named subviews. This is an array containing each of the child views of the stack view object. Figure 31-3, for example shows the view hierarchy for a stack view with four subviews:


Ios 9 stack view subviews.png

Figure 31-3


At any particular time, however, the stack view will not necessarily be responsible for arranging the layout and positions of all of the subviews it contains. The stack view might, for example, only be configured to arrange the Label3 and Label4 views in the above hierarchy. This essentially means that Label1 and Label2 may still be visible within the user interface but will not be positioned within the stack view. Subviews that are being arranged by the stack view are contained within a second array which is accessible via the arrangedSubviews property. Figure 31-4 shows both the subviews and the subset of the subviews which are currently being arranged by the stack view.


Ios 9 stack view arrangedsubviews.png

Figure 31-4


As will be outlined later in this chapter, the distinction between subview and arranged subviews is of particular importance when removing arranged subviews from a stack view.


StackView Configuration Options

A range of options are available to customize the way in which the stack view arranges its subviews. These properties are available both from within the Interface Builder Attributes Inspector panel at design time and also to be set dynamically from within the code of the app:

axis

The axis property controls the orientation of the stack in terms of whether the subviews are arranged in a vertical column layout or a horizontal row. When setting this property in code the axis should be set to UILayoutConstraintAxisVertical or UILayoutConstraintAxisHorizontal.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Distribution

The distribution property dictates the way in which the subviews of the stack view are sized. Options available are as follows:

  • Fill – The subviews are resized so as to fill the entire space available along the axis of the stack view. In other words the height of the subviews will be modified to fill the full height of the stack view in vertical orientation while the widths will be changed for a stack view in horizontal orientation. The amount by which each subview is resized relative to the other views can be controlled via the compression resistance and hugging priorities of the views (details of which were covered in the chapter entitled An Introduction to Auto Layout in iOS 10) and the position of the views in the stack view’s arrangedSubviews array.


Ios9 stack view fill.png

Figure 31-5


  • FillEqually – The subviews are resized equally to fill the stack view along the view’s axis. In a vertical stack, therefore, all of the subviews will be of equal height whilst in a horizontal axis orientation the subviews will be of equal width.


Ios9 stack view fill equal.png

Figure 31-6


  • FillProportionally – In this mode, the subviews are resized proportionally to their intrinsic content size along the axis of the stack view to fill the width or height of the view.
  • EqualSpacing – Padding is used to space the subviews equally to fill the stack view along the axis. The size of the subviews will be reduced if necessary in order to fit within the available space based on the compression resistance priority setting and the position within the arrangedSubviews array.


Ios9 stack view equalspacing.png

Figure 31-7


  • EqualCentering – This mode tries to position the subviews along the stack view’s axis such that the views have equal center to center spacing. The spacing used in this mode is influenced by the spacing property (outlined below). Where possible the stack view will honor the prevailing spacing property value, but will reduce this value if necessary. If the views still do not fit, the size of the subviews will be reduced if necessary in order to fit within the available space based on the compression resistance priority setting and the position within the arrangedSubviews array.


Ios9 stack view equalcentering.png

Figure 31-8


spacing

The spacing property specifies the distance (in points) between the edges of adjacent subviews within a stack view. When the stack view distribution property is set to FillProportionally the spacing value dictates the spacing between the subviews. In EqualSpacing and EqualCentering modes, the spacing value indicates the minimum allowed spacing between the adjacent edges of the subviews. A negative spacing value causes subviews to overlap.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

alignment

The alignment property controls the positioning of the subviews perpendicularly to the axis of the stack view. Available alignment options are as follows:

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

  • Fill – In fill mode, the subviews are resized to fill the space perpendicularly to the stack view’s axis. In other words, the width of the subviews in a vertical stack view are resized to fill the full width of the stack view.


Ios9 stack view alignment fill.png

Figure 31-9


  • Leading – In a vertically oriented stack view, the leading edges of the subviews are aligned with the leading edge of the stack view.


Ios9 stack view alignment leading.png

Figure 31-10


  • Trailing - In a vertically oriented stack view, the trailing edges of the subviews are aligned with the trailing edge of the stack view.


Ios9 stack view alignment trailing.png

Figure 31-11


  • Top – In a horizontally oriented stack view, the top edges of the subviews are aligned with the top edge of the stack view.


Ios9 stack view alignment top.png

Figure 31-12


  • Bottom - In a horizontally oriented stack view, the bottom edges of the subviews are aligned with the bottom edge of the stack view.


Ios9 stack view alignment bottom.png

Figure 31-13


  • Center – The centers of the subviews are aligned with the center axis of the stack view.


Ios9 stack view alignment center.png

Figure 31-14


  • FirstBaseline – Used only with horizontal stack views, this mode aligns all of the subviews with their first baseline. An array of subviews displaying text content, for example, would all be aligned based on the vertical position of the first line of text.


Ios9 stack view alignment firstbasline.png

Figure 31-15


  • LastBaseline – Similar to FirstBaseline, this mode aligns all of the subviews with their last baseline. For example, an array of subviews displaying text content would all be aligned based on the vertical position of the last line of text.


Ios9 stack view alignment lastbasline.png

Figure 31-16

baseLineRelativeArrangement

Used only for vertical stack views, this property is a Boolean value that controls whether or not the vertical spacing between subviews is arranged relative to the baseline of the text contained within the views.

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

layoutMarginsRelativeArrangement

A Boolean value which, if set to true, causes subviews to be arranged relative to the layout margins of the containing stack view. If set to false, the subviews are arranged relative to the edges of the stack view.

Creating a Stack View in Code

UIStackView instances can be created in code by passing through an array object containing the subviews to be arranged by the stack. Once created, all of the previously outlined properties may also be set dynamically from within the code. The following Swift code, for example, creates a new stack view object, configures it for horizontal axis orientation with FillEqually distribution and assigns two Label objects as subviews:

let labelOne = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
labelOne.text = "Hello"
labelOne.backgroundColor = UIColor.red

let labelTwo = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 21))
labelTwo.text = "There"
labelTwo.backgroundColor = UIColor.blue

let myStack = UIStackView(arrangedSubviews: [labelOne, labelTwo])

myStack.distribution = .fillEqually
myStack.axis = .horizontal

Adding Subviews to an Existing Stack View

Additional subviews may be appended to the end of a stack view’s arrangedSubviews array using the addArrangedSubview method as follows:

myStack.addArrangedSubview(labelThree)

Alternatively, a subview may be inserted into a specific index position within the array of arranged subviews via a call to the insertArrangedSubview:atIndex method. The following line of code, for example, inserts an additional label at index position 0 within the arrangedSubviews array of a stack view:

myStack.insertArrangedSubview(labelZero, atIndex: 0)

Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book

Hiding and Removing Subviews

To remove an arranged subview from a stack view, call the removeArrangedSubview method of the stack view object, passing through the view object to be removed.

myStack.removeArrangedSubview(labelOne)

It is important to be aware that the removeArrangedSubview method only removes the specified view from the arrangedSubviews array of the stack view. The view still exists in the subviews array and will probably still be visible within the user interface layout after removal (typically in the top left hand corner of the stack view).

An alternative to removing the subview is to simply hide it. This has the advantage of making it easy to display the subview later within the app code. A useful way to hide a subview is to obtain a reference to the subview to be hidden from within the arrangedSubviews array. The following code identifies and then hides the subview located at index position 1 in the array of arranged subviews:

let subview = myStack.arrangedSubviews[1]
subview.hidden = true

If the subview will not be needed again, however, it can be removed entirely by calling the removeFromSuperview method of the subview after it has been removed from the arrangedSubviews array as follows:

myStack.removeArrangedSubview(labelOne)
labelOne.removeFromSuperview()

This approach will remove the view entirely from the view hierarchy.

Summary

The UIStackView class allows user interface views to be arranged either in rows or columns. A wide range of configuration options combined with the ability to create and manage stack views dynamically from within code make this a powerful and flexible user interface layout solution.

With the basics of the UIStackView class covered in this chapter, the next chapter will create an example iOS app that makes use of this class.


Learn SwiftUI and take your iOS Development to the Next Level
SwiftUI Essentials – iOS 16 Edition book is now available in Print ($39.99) and eBook ($29.99) editions. Learn more...

Buy Print Preview Book



PreviousTable of ContentsNext
Implementing iOS 10 TableView Navigation using Storyboards in Xcode 8An iOS 10 Stack View Tutorial