1

I tried measuring the height of a view by using coordinatespace on it but the value it returns is the height of the full screen. Any idea why my code isn't giving me what I want ?

struct GeoReader: View {
    var body: some View {
        GeometryReader { geo in
            VStack {
                ZStack {
                    Rectangle()
                        .foregroundColor(.blue)
                    Text("Heigt of full screen is \(geo.size.height)")
                }
                ZStack {
                    Rectangle()
                        .foregroundColor(.red)
                        .coordinateSpace(name: "Redbox")
                    Text("Height of red box is \(geo.frame(in: .named("Redbox")).height)")
                }
            }
        }
    }
}

enter image description here

Bjorn Morrhaye
  • 687
  • 9
  • 30

2 Answers2

1

The geometry reader measures the entires screen, because you put the geometry reader right on top in the body of the view. It will therefore read the geometry of the view it returns. In this case the entire screen.

If you want to get the size of the two rectangles, you schoul put the geometry reader in the Stack of the rectangle and the text.

struct GeoReader: View {
    var body: some View {
        GeometryReader { geo1 in
            VStack {
                ZStack {
                    Rectangle()
                        .foregroundColor(.blue)
                    Text("Heigt of full screen is \(geo1.size.height)")
                }
                ZStack {
                    GeometryReader { geo2 in
                        Rectangle()
                            .foregroundColor(.red)
                            .coordinateSpace(name: "Redbox")
                        Text("Height of red box is \(geo2.frame(in: .named("Redbox")).height)")
                    }
                }
            }
        }
    }
}
MacUserT
  • 1,760
  • 2
  • 18
  • 30
1

The showing size is the dimension of the full view that is the container of the inner view.

You need to use another GeometryReader to get the inner dimension of a second ZStack.

struct ContentView: View {
    var body: some View {
        GeometryReader { geo in
            VStack {
                ZStack {
                    Rectangle()
                        .foregroundColor(.blue)
                    Text("Heigt of full screen is \(geo.size.height)")
                }
                GeometryReader { innterGeo in //<Here
                    ZStack {
                        Rectangle()
                            .foregroundColor(.red)
                            .coordinateSpace(name: "Redbox")
                        Text("Height of red box is \(innterGeo.frame(in: .named("Redbox")).height)")
                    }
                }
            }
        }
    }
}

if you need to use this in any places then you can use this approch.

First, create one struct and wrapped your content with GeometryReader.

struct GeometryContentSize<Content: View>: View {
    public var content: (CGSize) -> Content
    
    var body: some View {
        GeometryReader { geo in
            content(geo.size)
        }
    }
}

usage:

struct ContentView: View {
    var body: some View {
        GeometryReader { geo in
            VStack {
                ZStack {
                    Rectangle()
                        .foregroundColor(.blue)
                    Text("Heigt of full screen is \(geo.size.height)")
                }
                
                GeometryContentSize { (size) in //<--- Here
                    ZStack {
                        Rectangle()
                            .foregroundColor(.red)
                        Text("Height of red box is \(size.height)")
                    }
                }
            }
        }
    }
}
Raja Kishan
  • 16,767
  • 2
  • 26
  • 52