The text "Bottom Text" is intended to occupy some space at the bottom. However, when using a LazyVGrid with a scroll view, the content ends up being rendered behind the bottom text, and the scrollable area appears to stretch beyond the screen.
How can this issue be resolved?
Expected
Actual
struct HFlexibleView<Content: View>: View {
let triggerWidth: CGFloat
let content: () -> Content
///If this is set true, the view will be rendered normally, insead of being arranged flexibly
var disabled: Bool
var maxmumWidth: CGFloat
var columns: [GridItem] {
[GridItem(.adaptive(minimum: triggerWidth,
maximum: maxmumWidth))]
}
init(triggerWidth: CGFloat,
maxmumWidth: CGFloat = .infinity,
disabled: Bool = false,
@ViewBuilder content: @escaping () -> Content) {
self.triggerWidth = triggerWidth
self.maxmumWidth = maxmumWidth
self.disabled = disabled
self.content = content
}
var body: some View {
if disabled {
content()
} else {
GeometryReader { geometry in
LazyVGrid(columns: columns) {
content()
.frame(maxWidth: .infinity)
}
}
}
}
}
struct FlexbibleView_Previews: PreviewProvider {
static var previews: some View {
VStack {
HFlexibleView(triggerWidth: 500) {
ScrollView {
ForEach(0...20, id: \.self) {_ in
Image(systemName: "keyboard")
.font(.system(size: 30))
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 50)
.background(Color.green)
.cornerRadius(10)
}
}
}
Text("Bottom Text")
}
}
}
The docs for LazyVGrid
says: A container view that arranges its child views in a grid that grows vertically, creating items only as needed.
So you could use a specific size to constrain the content
(i.e the ScrollView
), such as:
GeometryReader { geometry in
LazyVGrid(columns: columns) {
content()
.frame(maxWidth: .infinity, maxHeight: geometry.size.height)
}
}