- Published on
Finally found a use case for .fixedSize š
- Authors

- Name
- Omar Elsayed
Introduction
If you told me a week ago that .fixedSize would save my afternoon, I would have laughed. The name alone screams "this will paint you into a corner"āwho actually wants their views locked to a static size? So like a lot of SwiftUI devs, I quietly filed it under "modifiers I'll never reach for."
Then a layout requirement landed on my desk that, surprise surprise š³, only .fixedSize could solve cleanly. And it taught me a lesson I should have learned years ago: there are no bad APIs, only APIs you haven't found the use case for yet. SwiftUI ships every modifier for a reason. Avoiding one on principle just shrinks your toolbox for no good reason.
Let me walk you through the problem.
The challenge
The brief was simple:
"We want all the items in the scroll view to take the same height as the biggest one."
Picture a horizontal ScrollView with an HStack inside. Each item is a card with a title and a description. The descriptions vary in lengthāsome short, some longāand the design team didn't want to truncate them. They just wanted every card to match the height of the tallest one so the row looks clean and intentional instead of jagged.

In the image above, the left card is shorter than the right one. The goal: make the left card stretch to match the right card's height, no matter which item happens to be the tallest.
Sounds trivial, right? It isn'tāespecially when you've spent years avoiding the one modifier that would unlock it š.
The first attempt (and why it backfired)
My first instinct was the obvious one: tell each card to fill all available vertical space.
ScrollView(.horizontal) {
HStack(alignment: .top, spacing: 16) {
ForEach(items) { item in
CardView(item: item)
.frame(maxHeight: .infinity, alignment: .topLeading)
}
}
}
The result?

Every card stretched to fill the entire screen height. Technically the cards were all the same height nowāmission accomplished, I guess?ābut the row was eating the whole viewport.
Here's why: the HStack had no height constraint of its own, so it accepted the proposed size from its parent (ScrollView), which is basically the full screen. Then .frame(maxHeight: .infinity) on each card happily stretched to fill that giant container.
So I had half the solution. The cards were matching each other's height. I just needed the HStack itself to stop being greedy and shrink down to "just tall enough to fit the tallest card."
The modifier I'd been avoiding
This is exactly what .fixedSize(horizontal: false, vertical: true) does. It tells a view: "ignore the proposed height from your parentāsize yourself to your ideal content height instead."
ScrollView(.horizontal) {
HStack(alignment: .top, spacing: 16) {
ForEach(items) { item in
CardView(item: item)
.frame(maxHeight: .infinity, alignment: .topLeading)
}
}
.fixedSize(horizontal: false, vertical: true) // š the one line that fixes everything
}
And the result:

Exactly what the designer asked for. Every card matches the tallest one, and the row is no taller than it needs to be.
Why this actually works š¤?
It's worth pausing on the layout dance happening here, because it's a great example of how SwiftUI's parent-proposes-child-decides model plays out:
ScrollViewproposes its full height to theHStack..fixedSize(vertical: true)intercepts that proposal and says: "thanks, but I'll size to my ideal height instead." TheHStack's ideal height is the height of its tallest child.HStackthen proposes that locked height down to each card..frame(maxHeight: .infinity)on each card stretches every card to fill that height.
So the two modifiers aren't fighting each otherāthey're a tag team. .fixedSize decides what the height should be (just enough for the tallest card), and .frame(maxHeight: .infinity) decides how every other card relates to it (fill it).
Take either one away and the whole thing falls apart. Without .fixedSize, the stack goes full-screen. Without .frame(maxHeight: .infinity), the shorter cards stay short and you're back to a jagged row.
Mission accomplished ā
The real lesson
I'll be honest: this took me about an hour and a half to figure out. Not because the solution is hardāit's literally one lineābut because I kept circling around .fixedSize instead of trying it. My brain had labeled it "dangerous" and refused to revisit that label.
The problem wasn't that the layout was tricky. It was that I'd shrunk my own toolbox.
The next time you catch yourself thinking "I never use that modifier"āstop and ask why. If the answer is "because the name sounds scary" or "I read a tweet once that said to avoid it," that's not a real reason. Every SwiftUI modifier exists because someone at Apple hit a layout problem it solves. Your job is to know which problem belongs to which tool.
Don't limit your solutions. The answer might be sitting right in front of you, wearing a name you've been ignoring š
subscribe for more like this