GeometryReader's size is 0 when enclosed inside NavigationView

Hi, so I have been learning SwiftUI for a while. Recently, I have been facing this and have not been able to find a solution for it. I have noticed that when GeometryReader is enclosed inside a NavigationView then width and height of size are both 0.

Code Block
var body: some View {
NavigationView {
GeometryReader { geometryProxy in
VStack {
ZStack {
/*
Here size.width and size.height are both 0
*/
draw_lines_of_quadrant(screen_width: geometryProxy.size.width, screen_height: geometryProxy.size.height)
}
}
}
}
}

This issue can be fixed if NavigationView is enclosed inside GeoemetyReader but it won't fix my issue as I plan to load another view which has GeometryReader inside it and it must be loaded inside NavigationView

Thanks

Accepted Reply

So is there any elegant way to find out if it's being evaluated the second time? 

Always be ready for being evaluated multiple times.

It crashes the view because of those 0s.

You may need to make your method 0-size-tolerant.
(Your code looks like an old C-code and very hard to read. I strongly recommend you to follow the modern coding rules. You are writing code in Swift, not C.)

Code Block
var body: some View {
NavigationView {
GeometryReader { geometryProxy in
VStack {
ZStack {
if geometryProxy.size != .zero {
draw_lines_of_quadrant(screen_width: geometryProxy.size.width, screen_height: geometryProxy.size.height)
}
}
}
}
}
}


Replies

As far as I tried, GeometryReader gives size 0 at the first time when body is evaluated, but gives the right screen size at the second time.

All such things may depend on the inner views.
Can you show the definition of draw_lines_of_quadrant(screen_width:screen_height:)?


By the way, snake_case_identifiers are not popular in Swift apps. You should better follow the standard coding styles of Swift.
So is there any elegant way to find out if it's being evaluated the second time? Actually I have drawn a grid in that method, so I have used range loop to draw it. It crashes the view because of those 0s. I saw a similar post on stackoverflow and it mentions what you have mentioned too.

Code Block swift
private func draw_lines_of_quadrant(screen_width: CGFloat, screen_height: CGFloat) -> some View {
Path { path in
/* Horizontal lines along x-axis */
for y_coord in Int(m_y_space_offset)..<Int(screen_height) {
/* This coordinate should not exceed the input width */
if y_coord < Int(screen_height) && y_coord % Int(m_x_space_offset) == 0 {
path.move(to: CGPoint(x: m_x_space_offset, y: max(m_y_space_offset, CGFloat(y_coord) - m_y_space_offset)))
path.addLine(to: CGPoint(x: screen_width - m_x_space_offset, y: max(m_y_space_offset, CGFloat(y_coord) - m_y_space_offset)))
}
}
/* Vertical lines along y-axis */
for x_coord in Int(m_x_space_offset)..<Int(screen_width) {
if x_coord < (Int(screen_width) - Int(m_x_space_offset)) && x_coord % Int(m_y_space_offset) == 0 {
path.move(to: CGPoint(x: CGFloat(x_coord), y: m_y_space_offset))
path.addLine(to: CGPoint(x: CGFloat(x_coord), y: max(0, screen_height - m_y_space_offset)))
}
}
}
.stroke(Color.black, lineWidth: m_stroke_width)
.colorInvert()
}


Thanks for replying.

So is there any elegant way to find out if it's being evaluated the second time? 

Always be ready for being evaluated multiple times.

It crashes the view because of those 0s.

You may need to make your method 0-size-tolerant.
(Your code looks like an old C-code and very hard to read. I strongly recommend you to follow the modern coding rules. You are writing code in Swift, not C.)

Code Block
var body: some View {
NavigationView {
GeometryReader { geometryProxy in
VStack {
ZStack {
if geometryProxy.size != .zero {
draw_lines_of_quadrant(screen_width: geometryProxy.size.width, screen_height: geometryProxy.size.height)
}
}
}
}
}
}


Thank you very much. Yes it's hard to read and kind of rough as am still learning Swift/SwiftUI

Thanks again
Just found out that you have to check both width and height against 0. Looks like either one can be zero too, that's what I just found out

Just found out that you have to check both width and height against 0. Looks like either one can be zero too, that's what I just found out

Thanks for sharing the info.