The following is supposed to create a Text
whose bounds occupy the entire screen, but it seems to do nothing.
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?
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.
To restate briefly what Dave explains in detail:
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.
Color.red
is different: in step 2, it just returns the proposed size as its own size. 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. 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:
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:
struct ContentView: View {
var body: some View {
ZStack {
Color.red
Text("hello")
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With