繁体   English   中英

SwiftUI:GeometryReader 中容器的不同 alignment 行为

[英]SwiftUI: Different alignment behavior of containers in GeometryReader

ZStack(alignment: .bottom)内的Text元素显示在容器底部(如预期)。 不过,如果相同的ZStackGeometryReader中,则 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 具有相同的性质,因为它总是尝试填充其父对象。

现在红色盒子不再被包围,并且有所有的空间(由清晰的颜色引起)可以自由移动(到底部)。

这是两个结果:

在此处输入图像描述

结论

.framealignment参数决定容器的拥抱“内框”在容器全框内的位置。 Containeralignment参数决定其内容放置在其“内部框架”(可以拥抱)内的位置。

暂无
暂无

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

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