Problem statement:
I have a child (HStack) inside a parent (Vstack). The HStack contains an unknown number of items with a fixed width, so its total width is also unknown.
I want to cut off the content of the HStack at the trailing edge, given by its “maximal allowed” width (the width that the HStack would expand to if it had for example a Color inside – see example).
Due to the Parent not having a fixed width though, the VStack gets stretched to the full width of the children, which can be wider than the screen.
Example:
Code to reproduce:
import SwiftUI
struct SwiftUITestView: View {
var body: some View {
VStack {
Text("Goal (visual):")
HStack {
ForEach(0...5, id: .self) { number in
Color(.blue)
.frame(width: 60, height: 60)
.cornerRadius(10)
.clipped()
}
Spacer()
}
.frame(maxWidth: 370, alignment: .leading) // <- without setting this fixed width...
.clipped()
.background(.red)
.padding(.vertical, 4)
Text("Problem:")
HStack {
ForEach(0...10, id: .self) { number in
Color(.blue)
.frame(width: 60, height: 60)
.cornerRadius(10)
.clipped()
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.background(.red)
.padding(.vertical, 4)
}
.padding(8)
.background(.green)
VStack {
Text("Size of HStack and VStack should be:")
HStack {
Color(.red).frame(height: 60)
}
.frame(maxWidth: .infinity, alignment: .leading)
.background(.red)
.padding(.vertical, 4)
}
.padding(8)
.background(.green)
}
}
#Preview {
SwiftUITestView()
}
I have found a workaround using a disabled horizontal ScrollView, but I would love to see how this can be done “the right” way.
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(0...10, id: .self) { number in
Color(.blue)
.frame(width: 60, height: 60)
.cornerRadius(10)
.clipped()
}
}
}.disabled(true)