I created very simple views with SwiftUI including ZStack.
struct ContentView: View {
var body: some View {
ZStack(alignment: .topLeading) {
Text("aaa")
.frame(width: 50, height: 50)
.font(.system(size: 20))
}
.frame(width: 142.0, height: 142.0)
.background(.pink)
}
}
I expected that the Text("aaa") would appear in the top leading of pink square.
But the result was this.
More strangely, it works well if I add 'Color.clear' to ZStack like this.
struct ContentView: View {
var body: some View {
ZStack(alignment: .topLeading) {
Color.clear
Text("aaa")
.frame(width: 50, height: 50)
.font(.system(size: 20))
}
.frame(width: 142.0, height: 142.0)
.background(.pink)
}
}
And the result it this.
I cannot understand this situation. SwiftUI is totally crazy.
Does anybody know about this?
CodePudding user response:
The elements of the ZStack
are laid out and aligned based on the size of the largest child, not the frame of the ZStack
itself.
You should think of the "content area" of the stack being seperate to the frame of the stack.
When you add a Color.clear
, its default frame is unbounded (the height and width are infinity
), so when it is added to the ZStack
, it will grow the "content area" to the maximum possible size.
This makes the content area of the stack the same size as the ZStack
s frame.
You can achieve the same result (in a clearer way) by using a Spacer()
with explicit infinite bounds.
This will ensure the children always fill the same available to them.
struct ContentView: View {
var body: some View {
ZStack(alignment: .topLeading) {
Spacer()
.frame(maxWidth: .infinity, maxHeight: .infinity)
Text("aaa")
.frame(width: 50, height: 50)
.font(.system(size: 20))
}
.frame(width: 142.0, height: 142.0)
.background(.pink)
}
}