Esowes
Esowes

Reputation: 297

Using GeometryReader with ScrollView

I'm trying to use GeometryReader to assign a maxHeight to a list in a Scrollview.
For the purpose of this question, I created the following project : GeometryReaderTesting.

It sets up a ContentView with a :
- Text.
- List.
- Text.
I extracted the List and last Text into their own view, using @ViewBuilder and I want to set the maxHeight of the List to .5 the height of my user's screen.

The problem is that the app won't build with the following errors, and the GeometryReader doesn't seem to be computing the correct height:

enter image description here

Here is my ContentView code, if anyone has an idea of what I'm doing wrong...

struct ContentView: View {

    let arrayWithStuff = [ "one","two","three","four","five","six","seven","eight","nine","ten", "eleven", "twelve"]

    var heightOfView: CGFloat = 0.0 // To be set by GeometryReader

    var body: some View {

    let myString = "Top of Test App"

     return   ZStack {
            GeometryReader { g in
                heightOfView = g.size.height
        NavigationView {

            print("height of view : \(heightOfView)")
             ScrollView {
                VStack {
                    Text(myString)
                    .padding()
                    Divider()
                    self.ViewBody()
                } // END of Vstack
                    .navigationBarTitle("Test App", displayMode: .inline)
            } // END of Scrollview
                }//End of NavigationView
            } // End of Geometry reader
        } // End of Zstack

  } // End of body


    @ViewBuilder func ViewBody() -> some View {
        VStack {
            List {
                ForEach (self.arrayWithStuff, id: \.self) { item in
                    Text(item) }
            } // END of List
                .frame(maxHeight: heightOfView*0.5)
            Divider()
            Text("Bottom of TEST APP")
        }
        .padding()
    }
}

Again, any help would be appreciated.

Upvotes: 1

Views: 1713

Answers (1)

Asperi
Asperi

Reputation: 257493

Here is a demo of possible solution. Tested with Xcode 11.4.

demo

struct ContentView: View {

    let arrayWithStuff = [ "one","two","three","four","five","six","seven","eight","nine","ten", "eleven", "twelve"]

    var body: some View {

        let myString = "Top of Test App"

        return   ZStack {
            GeometryReader { g in
                NavigationView {
                    ScrollView {
                        VStack {
                            Text(myString)
                                .padding()
                            Divider()
                            self.ViewBody(height: g.size.height)
                        } // END of Vstack
                            .navigationBarTitle("Test App", displayMode: .inline)
                    } // END of Scrollview
                }//End of NavigationView
            } // End of Geometry reader
        } // End of Zstack

    } // End of body


    func ViewBody(height: CGFloat) -> some View {
        print("height of view : \(height)")
        return VStack {
            List {
                ForEach (self.arrayWithStuff, id: \.self) { item in
                    Text(item) }
            } // END of List
                .frame(height: height*0.5)
            Divider()
            Text("Bottom of TEST APP")
        }
        .padding()
    }
}

Upvotes: 2

Related Questions