I'm currently working on a rather simple view: a bunch of H/VStacks on top of each other using a ZStack.
I'm constraining the size of my ZStack using the .frame modifier. For some reason my nested VStack seems to ignore its parent frame.
What I want to achieve is that the VStack matches the frame of the ZStack in the same way that the Image does.
struct CourseTileView: View {
let viewModel: CourseTileViewModel
var body: some View {
ZStack {
Image(uiImage: viewModel.thumbnail)
.resizable()
.scaledToFill()
.clipped()
VStack {
HStack {
HStack {
ForEach(viewModel.mediaTypes.sorted(), id: \.self) {
$0.image
.foregroundColor(.white)
.frame(width: 20, height: 20)
}
}
Spacer()
RedCapsuleTextView(title: "NEW")
.isHidden(!viewModel.isBadgeVisible)
}
Spacer()
Text(viewModel.title)
.foregroundColor(.white)
.font(.mpText.bold())
ProgressBar(
tintColor: .white,
backgroundColor: .white.alpha(0.3),
progress: viewModel.progress
)
.frame(width: 144, height: 7)
.isHidden(viewModel.progress == .zero)
}
.padding()
}
.frame(width: 164, height: 270)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}
The blue border is the size of the VStack reported in the preview:

Is it necessary to set a frame for the VStack as well?
Update
Using a GeometryReader would solve the problem, but... is that the way to go?
ZStack {
GeometryReader { geometry in
Image(uiImage: viewModel.thumbnail)
.resizable()
.scaledToFill()
.clipped()
VStack {
// Content
}
.frame(maxWidth: geometry.size.width)
.padding(.horizontal, Margin.small)
.padding(.vertical, Margin.medium)
}
.frame(width: 164, height: 270)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
