9.5 C
London
Sunday, September 15, 2024

How the relative measurement modifier interacts with stack views – Ole Begemann


I’ve yet another factor to say on the relative sizing view modifier from my earlier submit, Working with percentages in SwiftUI structure. I’m assuming you’ve learn that article. The next is nice to know if you wish to use the modifier in your individual code, however I hope you’ll additionally study some common tidbits about SwiftUI’s structure algorithm for HStacks and VStacks.

Utilizing relative sizing inside a stack view

Let’s apply the relativeProposed modifier to one of many subviews of an HStack:

HStack(spacing: 10) {
    Shade.blue
        .relativeProposed(width: 0.5)
    Shade.inexperienced
    Shade.yellow
}
.border(.main)
.body(peak: 80)

What do you count on to occur right here? Will the blue view take up 50 % of the obtainable width? The reply isn’t any. In truth, the blue rectangle turns into narrower than the others:

It’s because the HStack solely proposes a proportion of its obtainable width to every of its youngsters. Right here, the stack proposes one third of the obtainable house to its first baby, the relative sizing modifier. The modifier then halves this worth, leading to one sixth of the whole width (minus spacing) for the blue colour. The opposite two rectangles then turn out to be wider than one third as a result of the primary baby view didn’t burn up its full proposed width.

Order issues

Now let’s transfer the modifier to the inexperienced colour within the center:

HStack(spacing: 10) {
    Shade.blue
    Shade.inexperienced
        .relativeProposed(width: 0.5)
    Shade.yellow
}

Naively, I’d count on an equal outcome: the inexperienced rectangle ought to turn out to be 100 pt huge, and blue and yellow must be 250 pt every. However that’s not what occurs — the yellow view finally ends up being wider than the blue one:

I discovered this unintuitive at first, nevertheless it is sensible should you perceive that the HStack processes its youngsters in sequence:

  1. The HStack proposes one third of its obtainable house to the blue view: (620 – 20) / 3 = 200. The blue view accepts the proposal and turns into 200 pt huge.

  2. Subsequent up is the relativeProposed modifier. The HStack divides the remaining house by the variety of remaining subviews and proposes that: 400 / 2 = 200. Our modifier halves this proposal and proposes 100 pt to the inexperienced view, which accepts it. The modifier in flip adopts the dimensions of its baby and returns 100 pt to the HStack.

  3. Because the second subview used much less house than proposed, the HStack now has 300 pt left over to suggest to its closing baby, the yellow colour.

Necessary: the order through which the stack lays out its subviews occurs to be from left to proper on this instance, however that’s not at all times the case. Generally, HStacks and VStacks first group their subviews by structure precedence (extra on that under), after which order the views inside every group by flexibility such that the least versatile views are laid out first. For extra on this, see How an HStack Lays out Its Kids by Chris Eidhof. The views in our instance are all equally versatile (all of them can turn out to be any width between 0 and infinity), so the stack processes them of their “pure” order.

Leftover house isn’t redistributed

By now chances are you’ll have the option guess how the structure seems once we transfer our view modifier to the final baby view:

HStack(spacing: 10) {
    Shade.blue
    Shade.inexperienced
    Shade.yellow
        .relativeProposed(width: 0.5)
}
  • Blue and inexperienced every obtain one third of the obtainable width and turn out to be 200 pt huge. No surprises there.

  • When the HStack reaches the relativeProposed modifier, it has 200 pt left to distribute. Once more, the modifier and the yellow rectangle solely use half of this quantity.

The tip result’s that the HStack finally ends up with 100 pt left over. The method stops right here — the HStack does not begin over in an try and discover a “higher” resolution. The stack makes itself simply large enough to comprise its subviews (= 520 pt incl. spacing) and stories that measurement to its dad or mum.

Structure precedence

We will use the layoutPriority view modifier to affect how stacks and different containers lay out their youngsters. Let’s give the subview with the relative sizing modifier a better structure precedence (the default precedence is 0):

HStack(spacing: 10) {
    Shade.blue
    Shade.inexperienced
    Shade.yellow
        .relativeProposed(width: 0.5)
        .layoutPriority(1)
}

This ends in a structure the place the yellow rectangle really takes up 50 % of the obtainable house:

Rationalization:

  1. The HStack teams its youngsters by structure precedence after which processes every group in sequence, from highest to lowest precedence. Every group is proposed the total remaining house.

  2. The primary structure group solely comprises a single view, our relative sizing modifier with the yellow colour. The HStack proposes your complete obtainable house (minus spacing) = 600 pt. Our modifier halves the proposal, leading to 300 pt for the yellow view.

  3. There are 300 pt left over for the second structure group. These are distributed equally among the many two youngsters as a result of every subview accepts the proposed measurement.

Conclusion

The code I used to generate the photographs on this article is offered on GitHub. I solely checked out HStacks right here, however VStacks work in precisely the identical means for the vertical dimension.

SwiftUI’s structure algorithm at all times follows this fundamental sample of proposed sizes and responses. Every of the built-in “primitive” views (e.g. fastened and versatile frames, stacks, Textual content, Picture, Spacer, shapes, padding, background, overlay) has a well-defined (if not at all times well-documented) structure habits that may be expressed as a perform (ProposedViewSize) -> CGSize. You’ll have to study the habits for view to work successfully with SwiftUI.

A concrete lesson I’m taking away from this evaluation: HStack and VStack don’t deal with structure as an optimization drawback that tries to search out the optimum resolution for a set of constraints (autolayout fashion). Quite, they kind their youngsters in a specific means after which do a single proposal-and-response move over them. If there’s house leftover on the finish, or if the obtainable house isn’t sufficient, then so be it.

Latest news

A Slice of AI

Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here