简体   繁体   English

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

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

The following is supposed to create a Text whose bounds occupy the entire screen, but it seems to do nothing.下面应该创建一个Text ,其边界占据整个屏幕,但它似乎什么也没做。

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

The following hack:以下黑客:

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)
    }
}

seems to work however.但是似乎有效。

Is this a SwiftUI bug with relativeSize , or am I missing something?这是relativeSize的 SwiftUI 错误,还是我遗漏了什么?

You need to watch WWDC 2019 Session 237: Building Custom Views with SwiftUI , because Dave Abrahams discusses this topic, and uses Text in his examples.您需要观看WWDC 2019 会议 237:使用 SwiftUI 构建自定义视图,因为 Dave Abrahams 讨论了这个主题,并在他的示例中使用了Text

To restate briefly what Dave explains in detail:简要重申戴夫详细解释的内容:

  1. The parent (in this case, a root view created by the system and filling the screen) proposes a size to its child.父级(在这种情况下,由系统创建并填充屏幕的根视图)向其子级建议尺寸。
  2. The child chooses its own size , consuming as much or as little of the proposed size as it wants.孩子选择自己的尺寸,根据需要消耗尽可能多或尽可能少的建议尺寸。
  3. The parent positions the child in the parent's coordinate space based on various parameters including the size chosen by the child.父母根据各种参数(包括孩子选择的尺寸)将孩子定位在父母的坐标空间中。

Thus you cannot force a small Text to fill the screen, because in step 2, the Text will refuse to consume more space than needed to fit its content.因此你不能强迫一个小Text填满屏幕,因为在第 2 步中, Text将拒绝占用超出其内容所需的空间。

Color.red is different: in step 2, it just returns the proposed size as its own size. Color.red不同:在第 2 步中,它只是将建议的尺寸作为自己的尺寸返回。 We can call views like this “expandable”: they expand to fill whatever space they're offered.我们可以将这样的视图称为“可扩展的”:它们可以扩展以填充它们提供的任何空间。

ZStack is also different: in step 2, it asks its children for their sizes and picks its own size based on its children's sizes. ZStack也不同:在第 2 步中,它询问其子项的大小并根据其子项的大小选择自己的大小。 We can call views like this “wrapping”: they wrap their children tightly.我们可以将这样的视图称为“包裹”:它们紧紧地包裹着自己的孩子。

So if you promote Color.red to be the “main” view returned by body , and put the Text in an overlay, your ContentView will behave like Color.red and be expandable:因此,如果您将Color.red提升为body返回的“主”视图,并将Text放在叠加层中,您的ContentView将表现得像Color.red并且是可扩展的:

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

If you use a ZStack containing both Color.red and Text , the ZStack will wrap the Color.red , and thus take on its expandability:如果您使用同时包含Color.redTextZStack ,则ZStack将包装Color.red ,从而实现其可扩展性:

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

The following is supposed to create a Text whose bounds occupy the entire screen, but it seems to do nothing.下面应该创建一个Text其边界占据整个屏幕,但它似乎什么也不做。

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

The following hack:以下黑客:

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)
    }
}

seems to work however.然而,似乎工作。

Is this a SwiftUI bug with relativeSize , or am I missing something?这是一个带有relativeSize的 SwiftUI 错误,还是我遗漏了什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM