swift ignoresSafeArea使容器视图的高度大于其固有大小

hpcdzsge  于 2023-06-28  发布在  Swift
关注(0)|答案(1)|浏览(126)

我有一个奇怪的ignoresSafeArea viewModifier行为。据我所知,我的ContentView高度是通过顶部安全区域的插入量来增加的。为什么会这样?如果不使用GeometryReader,我该如何避免?也许我不明白这个视图修改器的想法,所以任何反馈都非常感谢。

  1. struct ContentView: View {
  2. var body: some View {
  3. Rectangle()
  4. .foregroundColor(.red)
  5. .frame(width: 400.0, height: 500)
  6. .ignoresSafeArea(.container, edges: .top)
  7. .background { Color.blue }
  8. }
  9. }
  10. struct ContentView_Previews: PreviewProvider {
  11. static var previews: some View {
  12. VStack(spacing: 0.0) {
  13. ContentView()
  14. Spacer()
  15. }
  16. }
  17. }

生成的布局:

我希望没有蓝色的背景,这是身体高度扩大的结果

q35jwt9p

q35jwt9p1#

欢迎来到Stack Overflow!您并没有误解.ignoresSafeArea(),而是误解了修饰符的顺序如何影响视图。除少数修改器外,所有修改器都返回一个包含前一个视图的视图。我把你的代码和重构成一个单一的视图,因为我认为这是混淆你以及。我对代码进行了注解,以帮助使其清晰。每个数字都是由后续视图 Package 的视图:

  1. struct IgnoresSafeAreaView: View {
  2. var body: some View {
  3. // 4. VStack
  4. VStack {
  5. // 1. Rectangle
  6. Rectangle()
  7. .foregroundColor(.red)
  8. // 2. Frame
  9. .frame(width: 400.0, height: 500)
  10. .ignoresSafeArea(.container, edges: .top)
  11. // 3. background
  12. .background { Color.blue }
  13. Spacer()
  14. }
  15. }
  16. }

上面的代码完全呈现了图片中显示的内容,因为最后,您的代码返回了VStack作为视图。因此,您有红色的矩形视图,蓝色背景视图的一瞥,以及Spacer(没有显示任何内容,因此显示为白色),所有这些都位于VStack中。
你真实的的困惑在于修饰语的顺序。首先创建一个红色矩形。这将跨越整个屏幕,除了顶部和底部的安全区域。
然后将该矩形放在一个恒定的400 x500帧内。它永远不会更多,它永远不会更少。这将简单地在屏幕上垂直居中矩形,而不是400 x500的大小。添加VStack不会改变这一点,因为VStack的垂直对齐是居中的。此时,VStack与矩形大小相同,因为它没有自己的大小。如果你在上面放一个.background(.green),你就看不到它了。
这是当前描述的代码:

  1. VStack {
  2. Rectangle()
  3. .foregroundColor(.red)
  4. .frame(width: 400.0, height: 500)
  5. }
  6. .background(.green)

在矩形后面添加Spacer(),您将看到绿色背景,这将进入安全区域,但矩形不会:

  1. VStack {
  2. Rectangle()
  3. .foregroundColor(.red)
  4. .frame(width: 400.0, height: 500)
  5. Spacer()
  6. }
  7. .background(.green)

如果你在矩形上加上.ignoresSafeArea(.container, edges: .top),或者简单的.ignoresSafeArea(edges: .top)(和这个视图没有区别),你会看到400 x500的矩形移动到安全区域。由于矩形在框架中,因此它不能增长,因此它会移动。但是,蓝色背景仍然可以看到矩形,而不会向上移动,因此它位于矩形后面,但对于.ignoresSafeArea()。这段代码很好地演示了这一点:

  1. VStack {
  2. Rectangle()
  3. .foregroundColor(.red.opacity(0.5))
  4. .frame(width: 400.0, height: 500)
  5. .ignoresSafeArea(edges: .top)
  6. .background { Color.blue }
  7. Spacer()
  8. }

在红色和蓝色重叠的地方,你会看到紫色,否则红色上的不透明度会使它看起来像粉红色。
现在让我们看看修改器的顺序。反转.frame().ignoresSafeArea()会导致矩形的大小增加,以占据安全区域,框架现在保持不变,不会移动,所以你再也看不到底部的蓝色(我认为你最初是例外)

  1. VStack {
  2. Rectangle()
  3. .foregroundColor(.red.opacity(0.5))
  4. .ignoresSafeArea(edges: .top)
  5. .frame(width: 400.0, height: 500)
  6. .background { Color.blue }
  7. Spacer()
  8. }

最后的答案是改变修饰符的顺序会完全改变你的结果,通常是以意想不到的方式。

展开查看全部

相关问题