3
ScrollView {
    VStack() {
        ForEach(0 ..< 5) { item in
            Text("Hello There")
                .font(.largeTitle)
         }
    }
}

The above code results in this:

enter image description here

When we add a GeometryReader, the views lose their sizing and spacing from one another (the .position modifier is just to center the text views within the GeometryReader):

ScrollView {
    VStack() {
        ForEach(0 ..< 5) { item in
            GeometryReader { geometry in
            Text("Hello There")
                .font(.largeTitle)
                .position(x: UIScreen.main.bounds.size.width/2)
            }
        }
    }
}

enter image description here

Can anybody share some help/advice around why this is the behavior and what I may want to look into in order to use a GeometryReader on center aligned views within a ScrollView as I'm trying to do here?

Adding a .frame(minHeight: 40) modifier to the ForEach is one way to force the views to take the space that the Text needs, but that is not a very nice or scalable solution.

Thank you!

RanLearns
  • 4,086
  • 5
  • 44
  • 81
  • `VStack` itself centres your Text views, as is visible on your first screenshots, so could you be more specific about what are you trying to do really? – Asperi Dec 02 '20 at 15:48
  • @ RanLearns: which dimensions you are trying to read in your project? As I could understand you are trying to read Text size, or you want to read the screen dimensions? – ios coder Dec 02 '20 at 18:29
  • @Omid Thanks for commenting. I am trying to read the Text's bounds rectangle (i.e. its minY position) within the ScrollView (0 at the top of the screen, negative if scrolled off the top). I am able to read this as needed using geometry.frame(in: .global).minY using the code posted in my question, but as you see the layout is badly affected. – RanLearns Dec 02 '20 at 20:28
  • If you just need to read the size, there is other ways as well, unless you want change the view with that size. why you need to read text size? – ios coder Dec 02 '20 at 20:39

1 Answers1

1

If you need just width of screen then place GeometryReader outside of scrollview:

GeometryReader { geometry in     // << here !!
  ScrollView {
    VStack() {
        ForEach(0 ..< 5) { item in
            Text("Hello There")
                .font(.largeTitle)
                .position(x: UIScreen.main.bounds.size.width/2)
            }
        }
    }
}

Can anybody share some help/advice around why this is the behavior

ScrollView does not have own size so GeometryReader cannot read anything from it and provides for own children some minimal dimension.

Asperi
  • 228,894
  • 20
  • 464
  • 690
  • 1
    Thanks for responding! In terms of the GeometryReader - when I move it outside of the ScrollView then geometry.frame(in: .local).minY is always 0 and geometry.frame(in: .global).minY is always 48 with safe area (or 0 with ignored SafeArea). I was using the GeometryReader as the container view of the Text because it was allowing me to keep track of the position of Text within the ScrollView. Your answer fixes the layout issue, but does not provide the information needed on the Text view's bounds rectangle – RanLearns Dec 02 '20 at 20:20
  • This sounds as you need something like https://stackoverflow.com/a/62588295/12299030. – Asperi Dec 03 '20 at 05:42