I'm having issues in using GeometryReader
and ZStack
. This is the code of my view:
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 20)
.fill(color.gradient.shadow(.drop(radius: 6)))
Text(title)
.foregroundColor(isBackgroundDark ? .white : .black)
}
.frame(height: 150)
.aspectRatio(contentMode: .fill)
}
This renders correctly as this:
If I put the code inside a GeometryReader
, to let the height of the view be proportional to the width, this happens (code, then image):
var body: some View {
GeometryReader { metrics in
ZStack {
RoundedRectangle(cornerRadius: metrics.size.width * 0.1)
.fill(color.gradient.shadow(.drop(radius: 6)))
Text(title)
.foregroundColor(isBackgroundDark ? .white : .black)
}
.frame(height: metrics.size.width / 3)
.aspectRatio(contentMode: .fill)
}
}
If I set the red
background on the ZStack
inside the GeometryReader
, this is what I see.
How can I solve this?
There are a couple things happening that are making your view look different then what you'd expect.
With those facts in mind, below are two solutions based around overcoming one of those two conditions listed above.
Since GeometryReader doesn't automatically center it's children, you'll have to do that yourself using the position modifier.
.position(x: metrics.frame(in: .local).midX, y: metrics.frame(in: .local).midY)
Append the above modifier to your ZStack to center it within the parent GeometryReader.
While GeometryReader can't center it's children, the Stacks (VStack, HStack, ZStack) can. Thus, you can center your content by placing your ZStack inside of a VStack whose frame fills the screen.
GeometryReader { metrics in
VStack {
ZStack {
RoundedRectangle(cornerRadius: metrics.size.width * 0.1)
.fill(color.gradient.shadow(.drop(radius: 6)))
Text(title)
.foregroundColor(isBackgroundDark ? .white : .black)
}
.frame(height: metrics.size.width / 3, alignment: .center)
.aspectRatio(contentMode: .fill)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
Again, you could use HStack here, or even another ZStack, if you prefer.