我怎样才能让 SwiftUI 视图完全填充它的超级视图?

How can I get a SwiftUI View to completely fill its superview?

下面是应该创建一个Text的bounds占满整个屏幕,但是好像什么都没做

struct ContentView: View {
    var body: some View {
        Text("foo")
            .relativeSize(width: 1.0, height: 1.0)
            .background(Color.red)
    }
}

以下技巧:

extension View {
    /// Causes the view to fill into its superview.
    public func _fill(alignment: Alignment = .center) -> some View {
        GeometryReader { geometry in
            return self.frame(
                width: geometry.size.width,
                height: geometry.size.height,
                alignment: alignment
            )
        }
    }
}

struct ContentView2: View {
    var body: some View {
        Text("foo")
            ._fill()
            .background(Color.red)
    }
}

不过似乎可行。

这是 relativeSize 的 SwiftUI 错误,还是我遗漏了什么?

您需要观看 WWDC 2019 Session 237: Building Custom Views with SwiftUI,因为 Dave Abrahams 讨论了这个主题,并在他的示例中使用了 Text

简要重申 Dave 详细解释的内容:

  1. parent(在本例中,由系统创建并填充屏幕的根视图)建议其 child 的大小。
  2. child 选择自己的大小,根据需要消耗尽可能多或尽可能少的建议大小。
  3. parent 根据各种参数(包括 child 选择的大小)将 child 定位在 parent 的坐标 space 中。 =47=]

因此你不能强迫一个小的 Text 填满屏幕,因为在第 2 步中,Text 将拒绝消耗比其内容所需更多的 space。

Color.red不同:在第2步中,它只是returns建议的尺寸作为自己的尺寸。我们可以称这样的视图为“可扩展”:它们可以扩展以填充所提供的任何内容 space。

ZStack 也不同:在第 2 步中,它会询问其 children 的大小,并根据其 children 的大小选择自己的大小。我们可以将这样的视图称为“包裹”:它们将 children 紧紧地包裹起来。

因此,如果您将 Color.red 提升为 body 返回的“主”视图,并将 Text 放在叠加层中,您的 ContentView 将表现得像Color.red 并可扩展:

struct ContentView: View {
    var body: some View {
        Color.red
            .overlay(Text("foo"))
    }
}

如果您使用包含 Color.redTextZStackZStack 将包装 Color.red,从而具有可扩展性:

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.red
            Text("hello")
        }
    }
}