.frame(height: nil) 的 SwiftUI 行为 [英] SwiftUI behavior of .frame(height: nil)

查看:30
本文介绍了.frame(height: nil) 的 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,我想要一个不是有限的宽度,它想要一个有限的宽度.

关于堆栈溢出的其他问题

我发现了两个问同样问题的问题:

为什么 .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

Apple docs

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆