The issue
I'm getting a thread issue that says "Invalid frame dimension (negative or non-finite)."
Here's my code:
struct CellStyle: ViewModifier { func body(content: Content) -> some View { content .frame(width: .infinity, height: 56, alignment: .center) .padding(.horizontal, 16) } }
The code runs fine, and I it seems to do what it's supposed to, so I'm confused at why it's giving me thread issue. Why will the code run without a finite width/height, contradictory to the Apple docs? (see the "Some reading" section below)
The fix
This code fixes the issue just fine, but I still wish I understood why the previous code doesn't crash or create an error.
struct CellStyle: ViewModifier { func body(content: Content) -> some View { content .frame(height: 56, alignment: .center) .frame(maxWidth: .infinity) .padding(.horizontal, 16) } }
As far as I can tell, it gives me that thread issue because I tell .frame
, that I want a width that isn't finite and it wants a width that's finite.
Other questions on stack overflow
I've found two questions that ask the same thing:
iOS 14 Invalid frame dimension (negative or non-finite)
SwiftUI iOS14 GeometryReader Invalid frame dimension
In the first question, the thread issue makes sense because given the code .frame(width: p.size.width - padding)
there's no guarantee that p.size.width
will be less than padding
. So as far as I can tell, it's an issue where the given value can be negative.
This issue I'm having has to do with the given value not being finite, so the questions don't relate.
The second question still hasn't been answered and is a bit vague, so it isn't that helpful for me right now. Maybe later someone will answer with a helpful answer, but as of yet, it's not helpful.
Some reading
Looking at the Apple docs I find this:
Use this method to specify a fixed size for a view’s width, height, or both. If you only specify one of the dimensions, the resulting view assumes this view’s sizing behavior in the other dimension.
So then why is it that .frame(width: .infinity, height: 56, alignment: .center)
even runs at all?
What does Apple mean by "the resulting view assumes this view’s sizing behavior in the other dimension."? Will it always assume that view to be a "push out" view, thus giving the same result as .infinity
?
I tested this and ran this code:
struct CellStyle: ViewModifier { func body(content: Content) -> some View { content .frame(height: 56, alignment: .center) .padding(.horizontal, 16) } }
It seems to give the same result, so now I'm curious is there ever a case in which swift "assuming" the width will result in a behavior other than .infinity
?
Final question
What's the behavior difference between .frame(width: .infinity)
vs .frame(width: nil)
(the equivalent of emitting either width or height).
func frame(width: CGFloat? = nil, height: CGFloat? = nil, alignment: Alignment = .center) -> some View
Thanks for the help!