简体   繁体   English

SwiftUI 中 ScrollView 底部对齐中的 VStack

[英]VStack inside ScrollView bottom alignment in SwiftUI

Currently building a chat application and I need new messages to appear at the bottom of the screen.目前正在构建一个聊天应用程序,我需要在屏幕底部显示新消息。 I also need to have messages aligned to the bottom.我还需要将消息对齐到底部。 However, using VStack inside ScrollView features top alignment by default.但是,在 ScrollView 中使用 VStack 默认情况下具有顶部对齐。

忙碌的swiftui

    ScrollView {
        VStack(alignment: .leading, spacing: 16) {
            Spacer()
            .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
            ForEach(notList, id: \.self) { not in
                NotRow(not: not)
                    
            }
            
        }
        .padding()
        .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, alignment: Alignment.topLeading)
        
    }

What should I do to fix this?我该怎么做才能解决这个问题?

A bit late to answer that one but it might help someone else.回答那个有点晚了,但它可能会帮助别人。 You could use a good old double rotation trick to achieve the result you want.您可以使用一个很好的旧双旋转技巧来实现您想要的结果。 Other solutions does not work because the maximum size inside a scroll view is undefined as it depends on its child views to compute its own content size.其他解决方案不起作用,因为滚动视图内的最大大小未定义,因为它取决于其子视图来计算自己的内容大小。

ScrollView {
  VStack(alignment: .leading, spacing: 16) {
      Spacer()
      .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
      ForEach(notList, id: \.self) { not in
          NotRow(not: not)
      }

  }
  .padding()
  .rotationEffect(Angle(degrees: 180))
}
.rotationEffect(Angle(degrees: 180))

I think you're missing a maxHeight in VStack我认为您在 VStack 中缺少 maxHeight

VStack(alignment: .leading) {
  Spacer().frame(maxWidth: .infinity)
  // content here
}
.frame(maxHeight: .infinity) // <- this

If you remove Spacer() and put it after the closing braces of your ForEach , it will fix it.如果您删除Spacer()并将其放在ForEach大括号之后,它将修复它。 Here is how your updated code will look like:更新后的代码如下所示:

ScrollView {
        VStack(alignment: .leading, spacing: 16) {
            .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
            ForEach(notList, id: \.self) { not in
                NotRow(not: not)

            }
            Spacer()
        }
        .padding()
        .frame(minWidth: 0, maxWidth: .infinity, minHeight:0, alignment: Alignment.topLeading)

    }

ScrollView does not propose the same height to its children ( VStack in this case) as it was proposed to it. ScrollView不会向其子项(在本例中为VStack )提出与建议的高度相同的高度。 It just asks for minimal size.它只是要求最小的尺寸。 The solution is to make its direct child respond with the minimum height which was proposed to ScrollView itself .解决方案是让它的直接子级响应建议给ScrollView本身的最小高度 We can achieve this by reading the proposed height via GeometryReader and setting that as minimum height of the child.我们可以通过GeometryReader读取建议的高度并将其设置为孩子的最小高度来实现这一点。

GeometryReader { reader in
    ScrollView {
        VStack {
            /// Spacer() or Color.red will now behave as expected
        }
        .frame(minHeight: reader.size.height)
    }
}

尝试将所有Alignment.topLeading更改为Alignment.bottomLeading

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

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