30
May
2022
SwiftUI Max Width Buttons in VStack
Reading time: 1 min
This recipe shows how to make all items in a VStack take up the same width as the widest item.
The end result looks like this:
The recipe has two components to it:
- Telling all items to use maximum width using
frame(maxWidth: .infinity)
. - Telling the
VStack
to take up the same width usingfixedSize
.
Here's the code:
VStack {
Group {
Button("Short") { }
Button("Longer one") { }
Button("The longest one by far") { }
}
.padding()
.frame(maxWidth: .infinity) // Set item width to max
.foregroundColor(.white)
.background(Color.red)
}
.fixedSize() // Set VStack width to match widest child
.background(Color.green)
The same recipe can be recursively applied if you have multiple stacked VStacks
. The only detail is that the child VStack
should drop its fixedSize
modifier:
VStack {
VStack {
Group {
Button("Short") { }
Button("Longer one") { }
Button("The longest one by far") { }
}
.padding()
.frame(maxWidth: .infinity)
.foregroundColor(.white)
.background(Color.red)
} // No fixedSize here
.background(Color.green)
Group {
Button("Really really really long one") { }
}
.padding()
.frame(maxWidth: .infinity)
.foregroundColor(.white)
.background(Color.cyan)
}
.fixedSize()
.background(Color.yellow)
Alternatively, the child VStack
can retain its original width, like this:
To do so, keep the fixedSize
modifier on the child VStack
as well:
VStack {
VStack {
Group {
Button("Short") { }
Button("Longer one") { }
Button("The longest one by far") { }
}
.padding()
.frame(maxWidth: .infinity)
.foregroundColor(.white)
.background(Color.red)
}
.fixedSize() // keep fixedSize
.background(Color.green)
Group {
Button("Really really really long one") { }
}
.padding()
.frame(maxWidth: .infinity)
.foregroundColor(.white)
.background(Color.cyan)
}
.fixedSize()
.background(Color.yellow)