![](/img/trans.png)
[英]SwiftUI erroneous vertical alignment of overlay when using GeometryReader
[英]SwiftUI: Different alignment behavior of containers in GeometryReader
ZStack(alignment: .bottom)
内的Text
元素显示在容器底部(如预期)。 不过,如果相同的ZStack
在GeometryReader
中,则 alignment 的行为不再相同。
这段代码:
var body: some View {
ZStack(alignment: .bottom) {
VStack {
Text("Outside geo")
}
GeometryReader { geo in
ZStack(alignment: .bottom) {
VStack {
Text("Inside geo")
}
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
产生这个结果:
如果我希望“内部地理”也放置在底部,我必须在其父 ZStack.frame(...) 修饰符中添加alignment: .bottom
。
这种行为的背景是什么? 为什么我可以在一种情况下使用ZStack(alignment: ...)
,而在另一种情况下必须使用ZStack {...}.frame(alignment: ...)
才能获得相同的结果?
它可能看起来很奇怪,但是GeometryReader
中的文本“Inside geo”在ZStack
的底部正确对齐 - 问题是您的ZStack
没有在GeometryReader
的底部对齐。
堆栈占据所需的最小空间量,而GeometryReader
具有相反的行为。 因此, GeometryReader
与高级ZStack
的底部对齐,但它占据了整个屏幕,而内层ZStack
位于GeometryReader
的中央。
尝试在每个视图上放置一个.background(someColor)
,您将看到它们的位置。
如果您希望“Inside geo”位于屏幕底部,您需要使用alignment
参数告诉ZStack
放置在底部 - 如下所示:
var body: some View {
ZStack(alignment: .bottom) {
VStack {
Text("Outside geo")
}
GeometryReader { geo in
ZStack(alignment: .bottom) {
VStack {
Text("Inside geo")
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) // Here you add the alignment parameter
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
经过实验,我现在知道是什么原因导致了这种行为,但首先还是觉得有点出乎意料。
当将 ZStack 的.frame max-size 设置为.infinity(将其拉伸)时,它的“内部尺寸”/内容仍然保持“拥抱” ,而不是也被拉伸。 意味着,容器的内容不一定总是使用它可以使用的所有空间。
举个例子:
ZStack(alignment: .bottom) {
Color.red
.frame(width: 50, height: 50)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.blue)
这会产生与添加第二个视图时完全不同的红色框位置,后者会推动容器的内部边界。
ZStack(alignment: .bottom) {
Color.red
.frame(width: 50, height: 50)
Color.clear
.frame(maxHeight: .infinity)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.blue)
透明颜色的框架现在推动了它的父母边界,因为它的高度试图尽可能地扩大。 GeometryReader 具有相同的性质,因为它总是尝试填充其父对象。
现在红色盒子不再被包围,并且有所有的空间(由清晰的颜色引起)可以自由移动(到底部)。
这是两个结果:
.frame
的alignment
参数决定容器的拥抱“内框”在容器全框内的位置。 Container的alignment
参数决定其内容放置在其“内部框架”(可以拥抱)内的位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.