UIStackView Tutorial: Introducing Stack Views

The original tutorial was created by Jawwad Ahmad. The Kevin Colligan update supports iOS 11, Xcode 9 and Swift 4.

Reproduced indicate: www.rockerhx.com/2018/08/21/…

Is there a need to dynamically add or remove view elements in iOS development? Do you want to go to the base hub and go through the third party library, or do you want to load the frame yourself, or update it with Auto Layout constraints? This disturbing demand, anyway I is resolute don’t choose the first two, even as a last resort, is also most updated constraints (although Auto Layout of wysiwyg greatly shortens the development time, increase the happy time I rolled cat, but had to admit that I am very disgusted with code to change constraints, visual encoding to code constraints, your mind!!!) . Deal with these requirements, in a word.

In this tutorial, learn how UIStackView provides an easy way to handle horizontal or vertical layouts. Also learn how to get a view by using attributes such as alignment, distribution, and spacing to self-adjust for easy adaptation.

This tutorial assumes a basic familiarity with Auto Layout. If you are not familiar with it, please go through the portal Beginning Auto Layout.

Start this tutorial

In this UIStackView tutorial, we’re going to use an app called “Vacation Spots.” This simple application displays some basic information about vacation locations. Don’t get messy and start, because there are a few issues that need to be addressed with UIStackView first, and it’s much easier than using auto layout alone. Start by downloading the introductory project for the UIStackView tutorial. Open the project and run it on the iPhone emulator. You’ll see a list of vacation spots.

Click on the London column to enter the information view for London. At first glance, it looks good, but there are a few problems.

  • Look at the row of buttons at the bottom of the view. Their current position is fixed, so they don’t fit the screen width. Press command-left to view the simulator horizontally.
  • Click on theWEATHEROn the side of theHideButton. It successfully hides the text, but it does not reposition the part below it, leaving a blank space.
  • The order of presentation of these sections can be improved. It would be more logical if the “What to See” section came right after the “Why Visit” section, instead of having the “weather” section in between.
  • In landscape mode, the bottom of the button is a little too close to the bottom edge of the view. If you can reduce the spacing between the elements, that’s even better.

Now that we have a list of improvements, let’s get started!!

Open the Main storyboard. The first time you do this, you are asked to select the initial device view. This view has no effect at runtime, resizes for different devices, and just makes the storyboard easier to use. An iPhone 7 or 8 will do.

View As: iPhone 7 “Or change at will.

Now openSpot Info View Controller

The various background colors of these labels and buttons are cleared at run time. In storyboards, they are just visual AIDS that help show how changing various StackView properties will affect the layout of its embedded views.

You don’t need to worry about this for now. If you really want to see the background color while running the application, you can temporarily comment out the following lines in the **viewDidLoad()** inside the SpotInfoViewController.

// Clear background colors from labels and buttons
for view in backgroundColoredViews {
    view.backgroundColor = UIColor.clear
}
Copy the code

In addition, all UI elements use explicit placeholders to make linking attributes easier and less likely.

@IBOutlet weak var whyVisitLabel: UILabel!
Copy the code

Let’s get started!

For the first time,

The first thing you do with stack View is fix the spacing between the bottom rows of the button. A Stack view can distribute its views along its axis in a variety of ways, one of which is equal spacing between views. To promote new controls, Apple can simply push the desired control element into the Stack View with one click. Open the Spot Info View Controller Story Edition scene and hold down Command to select the bottom three buttons.

Click on the bottom right corner Show Document Outlin:

Verify that the right button is selected in the left control set list:

When selected, click the New Stack button in the Auto Layout toolbar at the bottom right corner of the storyboard canvas:

The button will be embedded in the new stack view:

Now there is a constraint warning. Stack View is just a typographical form, inherited from UIView, which also needs constraints to determine the frame, and can only handle internal control layout once it determines its own frame.

When a control is embedded in a Stack View, any constraints on it are removed. For example, before embedding the button in the Stack View, the Submit Rating button has a vertical spacing constraint attached to the Ratinglabel at the top:

Click the Submit Rating button to see that it no longer contains any constraints.

⌘ to check control constraints also via the **Size inspector (⌥⌘5)** :

Next we need to add constraint control to the Stack View. If there are too many controls on the page to select a control, we can just select it from the list of controls on the left.

Another trick, hold Shift and right click, Xcode will help a lot.

Finally, add constraints from the Auto Layout Toolbar in the lower right corner.

Hold Constrain to Margins and add the following constraints.

Top: 20, Leading: 0, Trailing: 0, Bottom: 0
Copy the code

Enter the numbers as shown in the figure and just TAB. Adding constraints quickly and easily is preferred for agile development.

The controls now look like this, and the Stack View stretches the first control to fill the space.

Determines that the distribution property of the stack View internal control is distribution. Currently, it is set to Fill, which means that the contained control will be fully filled along its axis. To do this, the Stack View stretches only one view to fill the extra space; Specifically, it stretches the view with the lowest content hugging priority, or stretches the first view if all the controls have the same priority.

So geese, we’re just going to distribute them equally. Switch to the Attributes Inspector property editor and change the Distribution value from Fill to Equal Spacing:

Run to see if the bottom buttons are evenly spaced. It’s stable in portrait and landscape, but it’s not perfect. When you switch to a small screen, like an iPhone SE simulator, run.

Fortunately, Apple took this into account and we changed the Distribution property from Equal Spacing to Fill Proportionally, with a Spacing value of 10.

Now, run it again on the iPhone SE simulator, and this time it has to be awesome.

Stack View484 is so easy.

In the absence of stack Views, you have to use spacing views to place space, one space between each pair of buttons. To properly position spaced views, you must add equal width constraints to all spaced views as well as many additional constraints. It’s going to look something like this. To be visible in the screen shot, the interval view is given a light grey background:

If you do this once in a while, it’s fine, but if you do it more often, your boy’s body can’t handle it. Especially dynamically adding views. For example, hide the WEATHER in the example.

Now we simply set the spacing value, if you want to set up special spacing in a view, in iOS11 provide new Api: setCustomSpacing: afterView.

The old driver of the battlefield

After the exercise above, we can easily convert the required structure in the SpotInfoViewController into a stack view.

The rating section

Select the two controls in the RATING RATING section.

And then you do the same thing with the Stack button and embed it in the Stack view.

This time we only need to add three constraints:

Top: 20, Leading: 0, Bottom: 20
Copy the code

Spacing is 8:

You may see a misplaced view warning, as shown in the image below, in which the star label is out of the scope of the view (this warning may be due to some beta versions, so congratulations if it doesn’t appear) :

If you are sure your constraint is correct and your view is out of place because of a bug in some version of Xcode, use the Refresh Layout button in the lower right corner to correct it.

Now it looks normal.

Restore view

If it is found that sometimes hand damage, or for experimental purposes, more stack View, directly select the control to be removed, hold down Option, left click on stack to select Unembed.

Alternatively, select the control to undo it from the Editor \ Unembed menu.

Try the first vertical

Now to create a vertical stack view, select the WHY VISIT and **

** text controls.

Xcode will Orient the controls according to their distribution arrangement, as it does now, directly generating a vertically distributed stack view.

Now to determine the constraint, set the upper, left, and right constraints to 0, except that the object at the bottom is a relative WEATHER control with a spacing of 20.

The default alignment is left, as shown below:

Align attribute

The alignment property determines how the stack view is laid out perpendicular to its axis. For vertical stack views, the alignment can be set to:

  • , Fill the Fill,
  • To the left of Leading
  • Center to Qi Center
  • Right on Qi Trailing

The value of the horizontal stack view alignment property is slightly different:

The horizontal layout is aligned as follows:

  • Top alignment ·Top
  • To the left of Leading
  • Bottom to Bottom
  • Right on Qi Trailing
  • ·FirstBaseline: means the content baseline of the first UI element, with subsequent element content aligned to that baseline.
  • ·LastBaseline: means the content baseline of the last UI element, and the previous element content is aligned to that baseline.

You can select the vertical stack view that you just set and adjust the alignment properties to see what happens. Fill the Fill:

Left to Qi ·Leading:

Center to Qi ·Center:

Right on qi Trailing:

Run to see if the layout is stable.

Convert the “What to see” section

This part of the transformation is the same as in the previous section; you can just manipulate the key points directly.

  • First select the text elements WHAT TO SEE and **

    **.
  • Next, push into the stack view.
  • Alignment: Fill ·Fill.
  • Finally, set the following constraints.
Top: 20, Leading: 0, Trailing: 0, Bottom: 20
Copy the code

It will look something like this:

Convert the “weather” section

This part is tricky because of the need to hide the weather.

Let’s start by pushing all the elements in this section into the stack view. Select the WEATHER column and Hide button and press the horizontal stack view. Then press Command to select the **

** section of the column and press the horizontal stack view along with this section into the vertical stack view.

In fact, you can see that the horizontal stack view is covered by the Hide button. If you don’t like it, you can check the bottom alignment to see the effect.

In my experience, either change the constraint priority of UI elements in the horizontal stack view, or remove the Hide button and handle the constraint separately. Let’s do it separately just to make it easier to understand.

Self-retracting to the weather section of the original transition. Select WEATHER and **

** in this column:

Push it into the vertical stack view:

Then set the following constraints:

Top: 20, Leading: 0, Trailing: 0, Bottom: 20
Copy the code

The alignment is fill:

Because the Hide button is removed, we need to put constraints on it to ensure that the button is positioned correctly. Because we need to set the constraint’s relative control to the WEATHER column, we’ll have to modify it again. Select WEATHER directly from the Control list bar or control-shift-click:

Pressing into the stack view:

Alignment · Left Alignment ·Leading, Vertical Alignment ·Axis:

Run it to see what happens:

I’ll give you a shit. What’s going on? The button’s off? We actually forgot to set the constraint after we removed the Hide button. Hold down Control, select the Hide button, and drag it to the WEATHER column to add a constraint:

Just complete the following two constraints, spacing and vertical position constraints:

Run again. This time it must be right.

The stack,

In the list of controls on the left, select all of the controls we stackable previously:

Push all onto stack:

Then add a Constrain to the outer stack view by making sure to Constrain to Margins to 0. Then set Spacing ·Spacing to 20 and Alignment ·Alignment to Fill ·Fill.

The next time I run it, I still have the same problem.

Just remember that if there is a constraint on a peripheral relative to a control, as soon as it is stacked, the constraint will be removed, and you have to add it again:

Improve the level

Finally, we need to move the “What to See” section above the “Weather” section. The best way to do this is by dragging in the left control list:

If you drag directly in a Storyboard, you might mess up the structure by choosing the wrong control element.

Configure gaps based on screen size

Since space in the vertical direction is more valuable in landscape, it is safer to change the gap to 10 for landscape. Find the **+** button to the left of Spacing ·Spacing:

Select Any Width > Compact Height and then Add ·Add Variation:

Add a value of 10 to wAny hC column:

Let’s run it last, including traverse (⌘←) and see that 484 looks more comfortable.

animation

The current hide and render animations don’t look a little stiff and feel weird. Let’s add some animation to make the details look silky. Open the SpotInfoViewController. Swift, locating the updateWeatherInfoViews (hideWeatherInfo: animated:) method, now look like this:

weatherInfoLabel.hidden = shouldHideWeatherInfo
Copy the code

Replace it with the following code:

if animated { UIView.animate(withDuration: 0.3) {self. WeatherInfoLabel. IsHidden = shouldHideWeatherInfo}} else {weatherInfoLabel isHidden = shouldHideWeatherInfo }Copy the code

Find @ IBAction func weatherHideOrShowButtonTapped (_ sender: UIButton) method, replaced with the following code:

@IBAction func weatherHideOrShowButtonTapped(_ sender: UIButton) { let shouldHideWeatherInfo = sender.titleLabel! .text! == "Hide" updateWeatherInfoViews(hideWeatherInfo: shouldHideWeatherInfo, animated: shouldHideWeatherInfo) shouldHideWeatherInfoSetting = shouldHideWeatherInfo }Copy the code

Run like this, hide it so it won’t be awkward…

Write in the last

Business as usual, lazy cancer sufferers or fat people with poor reading comprehension will download the final code directly.

The use of UIStackView is here, on the use of UIStackView to do advanced animation is a little bit complicated, later free or need to open a special introduction.