I want to be able to show an array of notes in a ScrollView. Each of these objects contains a GeometryReader, and I'm having trouble setting each of these object's height by the amount of content that is in it.
I've made a reproducible example below (I know in this example it doesn't make sense why I need the geometry reader but I do need it in my actual app).
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView {
ForEach(notes) { note in
NoteView(note: note)
}
}
}
}
struct NoteView: View {
var note: Note = notes[0]
var body: some View{
GeometryReader { geo in
Text(note.content)
.fixedSize(horizontal: false, vertical: true)
.frame(width: geo.size.width)
}
}
}
struct Note: Identifiable {
var id = UUID()
var content: String = ""
}
var notes = [
Note(content: "Lorem ipsum dolor sit amet, consectet adipiscing elit. Condimentum quisque id vitae convallis dignissim pharetra nisl est creatus"),
Note(content: "Mauris ac tempor libero, non eleifend lectus. Mauris eu hendrerit nunc. Donec at ante mauris. Duis ac elit purus. Mauris ullamcorper mi."),
Note(content: "Lorem ipsum dolor sit amet, consectet adipiscing elit. Condimentum quisque id vitae convallis dignissim pharetra nisl est creatus"),
Note(content: "Mauris ac tempor libero, non eleifend lectus. Mauris eu hendrerit nunc. Donec at ante mauris. Duis ac elit purus. Mauris ullamcorper mi.")
]
When I use embed the ForEach loop in a ScrollView all of the items overlap:
But if I change the ScrollView to a VStack, I get more what I am looking for with the items appearing stacked on top of each other.
I believe that overlapping is because the height of the GeometryReader is less than the height of the Text within the GeometryReader.
If I manually add .frame(height: 100) to the GeometryReader, the objects no longer overlap. But I do not know how I could create a variable for the height that would be based on the amount of Text each note contains.
CodePudding user response:
Try with frame()
Example :
Text(myText).frame(height: 100)
Hope it will work
CodePudding user response:
You don't need GeometryReader
for that, it can be done just with .frame
capabilities, like
struct NoteView: View {
var note: Note = notes[0]
var body: some View{
Text(note.content)
// .fixedSize(horizontal: false, vertical: true) // this might be not needed as well
.frame(maxWidth: .infinity) // << here !!
}
}