Home > front end >  Using a Geometry Reader within a ScrollView is causing items to overlap
Using a Geometry Reader within a ScrollView is causing items to overlap

Time:07-02

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: Items overlapping when using ScrollView

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.

VStack allows the correct height of the object

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 !!
    }
}
  • Related