.frame(height: nil) 的 SwiftUI 行为

Mik*_*iss 6 swift swiftui

问题

我收到一个线程问题,上面写着“无效的框架尺寸(负或非有限)”。

这是我的代码:

struct CellStyle: ViewModifier {
    func body(content: Content) -> some View {
        内容
            .frame(宽度:.infinity,高度:56,对齐方式:.center)
            .padding(.horizo​​ntal, 16)
    }
}

代码运行良好,我似乎做了它应该做的,所以我很困惑为什么它给我线程问题。为什么代码会在没有有限宽度/高度的情况下运行,与 Apple 文档相矛盾?(请参阅下面的“一些阅读”部分)

修复

这段代码很好地解决了这个问题,但我仍然希望我理解为什么以前的代码不会崩溃或产生错误。

struct CellStyle: ViewModifier {
    func body(content: Content) -> some View {
        内容
            .frame(高度:56,对齐:.center)
            .frame(maxWidth: .infinity)
            .padding(.horizo​​ntal, 16)
    }
}

据我所知,它给了我那个线程问题,因为我告诉我.frame,我想要一个不是有限的宽度,它想要一个有限的宽度。

堆栈溢出的其他问题

我发现了两个问同样问题的问题:
iOS 14 Invalid frame dimension (negative or non-finite)

SwiftUI iOS14 GeometryReader 无效的框架尺寸

在第一个问题中,线程问题是有道理的,因为给定代码.frame(width: p.size.width - padding),不能保证p.size.width小于padding. 因此,据我所知,这是一个给定值可能为负的问题。
我遇到的这个问题与给定的值不是有限的有关,所以这些问题不相关。
第二个问题还没有回答,有点含糊,所以现在对我来说不是那么有帮助。也许稍后有人会回答一个有用的答案,但到目前为止,它没有帮助。

一些阅读

查看Apple 文档,我发现:

使用此方法为视图的宽度、高度或两者指定固定大小。如果您仅指定其中一个维度,则生成的视图将假定此视图在另一个维度中的大小调整行为。

那么为什么它.frame(width: .infinity, height: 56, alignment: .center)甚至会运行呢?
Apple 所说的“结果视图假定此视图在另一个维度中的大小调整行为”是什么意思?它是否总是假设该视图是“推出”视图,从而给出与.infinity?

我对此进行了测试并运行了以下代码:

struct CellStyle: ViewModifier {
    func body(content: Content) -> some View {
        内容
            .frame(高度:56,对齐:.center)
            .padding(.horizo​​ntal, 16)
    }
} 

它似乎给出了相同的结果,所以现在我很好奇是否有过快速“假设”宽度会导致除.infinity?

最后的问题

.frame(width: .infinity)vs .frame(width: nil)(相当于发射宽度或高度)之间的行为差​​异是什么?

func frame(width: CGFloat? = nil, height: CGFloat? = nil, alignment: Alignment = .center) -> some View

苹果文档

谢谢您的帮助!

Mik*_*iss 7

.frame(width: nil) 的作用

基本上 .frame 将采用给定的值并返回另一个使用您输入的值更新的视图。
如果省略其中一个参数或将其设置为 nil,那么它将采用前一个视图各自的宽度/高度值。

测试代码:

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上述代码的结果图

为什么 .frame(width: .infinity) 仍然运行

.infinityApple doc on .infinity)是类型Float,因此没有办法.frame不排除它,但它仍然会产生问题。(因此线程问题)

感谢Mark Moeykens帮助我找到了这个答案!

注意:.frame(maxWidth: .infinity)代替.frame(width: .infinity)