I'm building an iOS Widget (WidgetKit) with a 2×2 button grid using GeometryReader to calculate row heights. The buttons should fill their containers completely and have equal heights, like Apple's Shortcuts widget.
Expected Result: All buttons should have equal height and fill the available space evenly, like this:

Actual Result: The button backgrounds don't fill their calculated container heights. The containers themselves ARE equal (verified with debug borders showing 44pt height), but the button content/background stops short:

Current Implementation:
Using GeometryReader to calculate cellHeight, then applying it with .frame(height: cellHeight):
GeometryReader { geo in
let cellHeight = (geo.size.height - totalSpacing - totalPadding) / 2
VStack(spacing: 8) {
ForEach(0..<2) { row in
HStack(spacing: 8) {
ForEach(0..<2) { col in
WidgetActionButton(...)
.frame(height: cellHeight)
}
}
}
}
}
Button implementation:
Button(intent: ExecuteWidgetActionIntent(...)) {
VStack(alignment: .leading, spacing: 8) {
Image(systemName: action.iconName)
Spacer(minLength: 0)
Text(action.displayName)
}
.padding(12)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.background(Color.blue)
.clipShape(RoundedRectangle(cornerRadius: 14))
}
.buttonStyle(.plain)
The debug borders prove the containers are equal height, but the colored button backgrounds don't expand to fill them. How can I make the button backgrounds fill the full calculated height in WidgetKit?
Grid with
.frame(maxHeight: .infinity)on buttons:- Applied
.frame(maxHeight: .infinity)to each button in GridRow - Expected: Rows would distribute height equally
- Result: Top row still taller than bottom row
- Applied
Grid with
.gridCellUnsizedAxes(.vertical):- Added
.gridCellUnsizedAxes(.vertical)to GridRow - Expected: Grid would ignore intrinsic content size and distribute evenly
- Result: No change, rows still unequal
- Added
GeometryReader with VStack/HStack and calculated heights:
- Calculated exact
cellHeightusing available space - Applied
.frame(height: cellHeight)to each button container - Expected: Buttons would fill the fixed height containers
- Result: Container heights are correct (verified with debug borders at 44pt), but button backgrounds don't expand to fill them
- Calculated exact
.frame(maxHeight: .infinity)inside Button label:- Applied maxHeight to the VStack inside Button's label closure
- Expected: Button content would expand to fill available space
- Result: Button label still doesn't fill the container height
ZStack with background outside Button:
- Wrapped Button in ZStack with Color background
- Expected: Background would fill the container independently
- Result: Background also doesn't fill the calculated height
The core issue: In WidgetKit, the button content seems to have its own intrinsic size that doesn't respond to the parent container's fixed height, even though debug borders confirm the containers are equal.
Edit:
[![My Widget now][1]][1] [1]: https://i.sstatic.net/fzg3MSR6.png
[![ When you compare my widget to Apple's Shortcuts widget in the screenshots, you can see:
- Apple's buttons are much larger
- Apple's buttons are much closer to the widget edges
- Less spacing between buttons ][2]][2] [2]: https://i.sstatic.net/2vuawM6N.png
