Open j-f1 opened 3 years ago
I noticed issues with overlay and background when working on preference keys. In SwiftUI they seem to clip to their parents bounds (which we can do when it’s just a simple color but not otherwise). Maybe we could use geometry reader to get the parents size and set the overlay/background bounds accordingly?
I spent some time experimenting with how SwiftUI lays out .overlay
(and the related ZStack
). Here are my observations:
foo.overlay(bar)
computes the size of foo
first, then sets the ideal size of bar
to match foo
’s size.foo.overlay(bar)
computes the resulting view’s position and size in the layout using only information from foo
. If bar
is larger than foo
, it simply extends beyond foo
without taking up any space in the layout.ZStack { foo; bar }
computes the size of foo
and bar
completely independently, differing from ZStack { bar; foo }
only in which view appears “on top” of the other.ZStack { foo; bar }
computes the stack’s size as the largest of its children’s sizes along each axis. It then lays out its children in that space according to its alignment
.Here’s a visual summary:
```swift VStack { Text("ZStack") .font(.system(.title2, design: .monospaced)) ZStack(alignment: alignment) { Color.red // .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) } ZStack(alignment: alignment) { Color.red .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) } ZStack(alignment: alignment) { Color.red // .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) } ZStack(alignment: alignment) { Color.red .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 150, height: 150) } ZStack(alignment: alignment) { Color.red .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) } } ``` | ```swift VStack { Text("overlay") .font(.system(.title2, design: .monospaced)) Color.red // .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) , alignment: alignment ) Color.red .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) , alignment: alignment ) Color.red // .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) , alignment: alignment ) Color.red .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 150, height: 150) , alignment: alignment ) Color.red .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) , alignment: alignment ) } ``` |
When rendering this at first, the expected gray stroke does not appear. After manually removing the
width: 0; height: 0;
parameter to the SVG element describing the circle, this appears:Note that the circle actually appears underneath the image, and that the circle’s shape does not match the image’s shape.
The first issue can be resolved by setting the
z-index
of the second generatedgrid-area
to 1, which appears to be necessary because theclip-path
property creates a new stacking context.I’m not sure how to resolve the second issue.