NavigationView + GeometryReader views return incorrect size

Viewed 377

For:

struct ContentView: View {
        var body: some View {
            NavigationView {
                GeometryReader { geometry -> Text in
                    print("geometry.size \(geometry.size)")
                    return Text("text")
                }
            }
        }
    }

Output:

geometry.size (0.0, 0.0)

geometry.size (428.0, 749.0)

For:

struct ContentView: View {
        var body: some View {
            GeometryReader { geometry -> Text in
                print("geometry.size \(geometry.size)")
                return Text("text")
            }
        }
    }

Output:

geometry.size (428.0, 749.0)

Is it a bug? Is it possible to avoid such behavior?

1 Answers

I don't believe this is a bug; any view has the right to reposition its subviews over its lifetime. Normally this behavior should make no difference to you, as the views will automatically get updated as the geometry changes.

However, if there is some logic you need done right when the geometry.size is updated to a non-zero value, you can monitor this in an onChange(of:) block:

struct ContentView: View {
  var body: some View {
    NavigationView {
      GeometryReader { geometry in
        Text("text")
          .onChange(of: geometry.size) { newSize in
            if newSize != .zero { /* do something with newSize */ }
          }
        }
    }
  }
}

I talk more about this behavior and ways to work around it in this other stackoverflow article

Related