.frame(height: nil) 的 SwiftUI 行为 [英] SwiftUI behavior of .frame(height: nil)
问题描述
问题
我收到一个线程问题,显示无效的框架尺寸(负或非有限)."
这是我的代码:
struct CellStyle: ViewModifier {func body(content: Content) -> some View {内容.frame(宽度:.infinity,高度:56,对齐方式:.center).padding(.horizontal, 16)}}
代码运行良好,我似乎做了它应该做的,所以我很困惑为什么它给我线程问题.为什么代码会在没有有限宽度/高度的情况下运行,与 Apple 文档相矛盾?(请参阅下面的一些阅读"部分)
修复
这段代码很好地解决了这个问题,但我仍然希望我理解为什么以前的代码不会崩溃或产生错误.
struct CellStyle: ViewModifier {func body(content: Content) -> some View {内容.frame(高度:56,对齐:.center).frame(maxWidth: .infinity).padding(.horizontal, 16)}}
据我所知,它给了我那个线程问题,因为我告诉 .frame
,我想要一个不是有限的宽度,它想要一个有限的宽度.
关于堆栈溢出的其他问题
我发现了两个问同样问题的问题:
为什么 .frame(width: .infinity) 仍然运行
.infinity
(Apple doc on .infinity) 是 Float
类型,所以 .frame
没有办法不排除它,但它仍然会产生问题.(因此线程问题)
感谢 Mark Moeykens 帮助我找到这个答案!
注意:.frame(maxWidth: .infinity)
而不是 .frame(width: .infinity)
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!
What .frame(width: nil) does
Basically .frame will take the given values and return another view that is updated with the values you put.
If you omit one of the parameters or set it to nil, then it will take the respective width/height value of the previous view.
Test code:
struct ContentView: View {
@State var keyValue = ""
var body: some View {
VStack(spacing: 10) {
Text("Something")
.background(Color.blue)
Text("Something")
.frame(width: 300, height: nil, alignment: .center)
.background(Color.blue)
Text("Something")
.frame(width: nil, height: 200, alignment: .center)
.background(Color.blue)
Text("Something")
.frame(width: nil, height: nil, alignment: .center)
.background(Color.blue)
}
}
}
Why .frame(width: .infinity) still runs
.infinity
(Apple doc on .infinity) is of type Float
, so there's no way for .frame
not to except it, but it still can create problems. (Thus the thread issue)
Thanks to Mark Moeykens for the help in getting me to this answer!
Note: .frame(maxWidth: .infinity)
instead of .frame(width: .infinity)
这篇关于.frame(height: nil) 的 SwiftUI 行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!