1

I have the following view:

var body: some View {
    ScrollView {
        VStack {
            HStack {
                Text("Something")
                Text("Something")
            }
            GeometryReader { geo in
                VStack {
                    CustomView(param: geo.size.width * 0.3) // I need these views to know the size so they can align internal components
                    CustomView(param: geo.size.width * 0.3)
                    CustomView(param: geo.size.width * 0.3)
                }.frame(width: geo.size.width, height: geo.size.height) // Tried also without setting height here
            }
            Button(action: {
                print("Hey")
            }) {
                Text("Push me")
            }
        }.padding()
    }
}

The above results in the portion containing the GeometryReader overlapping the views above, and the Button at the end being on top of the GeometryReader. The result is similar if I wrap the GeometryReader in another VStack.

Is there anyway to fix this behavior? I need the GeometryReader for the reason explained in the code comments (or perhaps and equivalent solution, since I need to size the elements' inner contents in a specific way).

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
Azurlake
  • 612
  • 1
  • 6
  • 29

1 Answers1

1

Move GeometryReader outside of ScrollView, like

var body: some View {
  GeometryReader { geo in     // << here !!
    ScrollView {
        VStack {
            HStack {
                Text("Something")
                Text("Something")
            }
            VStack {
                CustomView(param: geo.size.width * 0.3)
                CustomView(param: geo.size.width * 0.3)
                CustomView(param: geo.size.width * 0.3)
            }.frame(width: geo.size.width, height: geo.size.height)

            Button(action: {
                print("Hey")
            }) {
                Text("Push me")
            }
        }.padding()
    }
  }
}

*Note: GeometryReader does not work in ScrollView because ScrollView does not have own geometry, it tries to read geometry from content, so there is cycling.

Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Thank you, that worked. It bothers me though, that even setting an explicit height to the GeometryReader view is causing strange behaviour on the layout of surrounding views. Also, it bothers me the fact that Swift enforces things like the guard construct in order to reduce nesting of the "happy result" path, but forces us to wrap everything in SwiftUI in unnecessary `Group`s, and now this also... humpf. – Azurlake Jul 02 '22 at 22:06