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:

Screenshot%202022-06-03%20at%2008.48.28

The recipe has two components to it:

  1. Telling all items to use maximum width using frame(maxWidth: .infinity).
  2. Telling the VStack to take up the same width using fixedSize.

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:

Screenshot%202022-06-03%20at%2008.49.02

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:

Screenshot%202022-06-03%20at%2008.48.49

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)

Next Post Previous Post