【问题标题】:VStack inside ScrollView bottom alignment in SwiftUISwiftUI中ScrollView底部对齐内的VStack
【发布时间】:2019-09-15 17:49:55
【问题描述】:

目前正在构建一个聊天应用程序,我需要在屏幕底部显示新消息。我还需要让消息与底部对齐。但是,在 ScrollView 中使用 VStack 默认情况下具有顶部对齐功能。

    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)
        
    }

我应该怎么做才能解决这个问题?

【问题讨论】:

  • 你想让空白区域可以滚动吗?
  • 我希望它在聊天应用程序中表现得像:你可以做很少的滚动,但消息会返回到底部。

标签: ios swift swiftui vstack


【解决方案1】:

回答这个问题有点晚,但它可能对其他人有所帮助。您可以使用一个很好的旧双旋转技巧来实现您想要的结果。其他解决方案不起作用,因为滚动视图内的最大大小未定义,因为它取决于其子视图来计算自己的内容大小。

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))

【讨论】:

    【解决方案2】:

    我认为您在 VStack 中缺少 maxHeight

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

    【讨论】:

    • 哇,不得不这样做似乎有点不雅。但它对我有用!
    【解决方案3】:

    ScrollView 不会向它的孩子(在这种情况下为VStack)建议与向它建议的高度相同的高度。它只是要求最小的尺寸。解决方案是让其直接子代以建议给ScrollView 本身的最小高度 进行响应。我们可以通过GeometryReader 读取建议的高度并将其设置为孩子的最小高度来实现这一点。

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

    【讨论】:

      【解决方案4】:

      如果您删除 Spacer() 并将其放在 ForEach 的右大括号之后,它将修复它。更新后的代码如下所示:

      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)
      
          }
      

      【讨论】:

        【解决方案5】:

        尝试将您的所有Alignment.topLeadings 更改为Alignment.bottomLeading

        【讨论】:

          猜你喜欢
          • 2020-07-16
          • 2020-10-29
          • 2021-03-29
          • 1970-01-01
          • 2020-05-16
          • 2020-12-07
          • 1970-01-01
          • 2017-11-23
          • 2021-07-21
          相关资源
          最近更新 更多