Swiftui 将 VStack 子项高度调整为内容高度

Posted

技术标签:

【中文标题】Swiftui 将 VStack 子项高度调整为内容高度【英文标题】:Swift UI adjust VStack children height to content height 【发布时间】:2021-10-01 10:27:08 【问题描述】:

我有一个带有三个孩子的 VStack。这些孩子中的每一个都有一个 HStack,左边有一些文本和一个空白区域。这是预览的屏幕截图,其中 VStack 子项周围带有突出显示的边框,每个 HStack 周围都有突出显示的边框。

如何将每个 VStack 子项设置为缩小到 HStack 的高度并消除底部的空白空间?现在问题似乎是由默认情况下 VStack 填充整个屏幕并将每个孩子设置为相等的高度引起的。

当前代码:

import Foundation
import SwiftUI


struct NameAndConnection: View 
    var body: some View 
        VStack(alignment: .leading) 
            Text(data.name)
               .font(.headline)
               .fontWeight(.semibold)
               .foregroundColor(Color.black)
               .frame(alignment: .leading)
   
            Text(data.connection)
               .font(.callout)
               .fontWeight(.medium)
               .foregroundColor(Color.gray)
               .frame(alignment: .leading)
        
    


struct Description: View 
    var body: some View 
        Text(data.description)
    


struct Post: View 
    var body: some View 
        GeometryReader  geo in
            HStack(alignment: .top, spacing: 0) 
                Spacer()
                VStack(alignment: .leading) 
                    NameAndConnection()
                    Description()
                        .padding(.top, 1.0)
                
                .frame(width: geo.size.width * 0.75)
            
        
    




struct PostView: View 
    var body: some View 
        GeometryReader  geo in
            VStack() 
                Post()
                Post()
                Post()
            
        
    

【问题讨论】:

添加一个frame()怎么样? 如何从 HStack 获取高度信息到 VStack frame()? 添加您当前的代码。在没有它的情况下尝试调试有点没用。您可能只需要在最低的下方添加一个Spacer() 添加了当前代码。添加 Spacer 是否会强制 VStack 不再将空间平均分配给孩子,而是让孩子的 HStack 控制空间? 请添加代码,而不是代码图片,不能复制/粘贴,不可搜索等。确保它是minimal reproducible example——到目前为止您发布的内容实际上无法使用任何人,因为它依赖于自定义类型。 【参考方案1】:

GeometryReader 将占用所有可用空间。一般而言,尽量少用GeometryReader 并针对不同的屏幕尺寸提出其他更灵活的解决方案,这被广泛认为是一种好的做法。

当您必须使用它时,通常测量View 的背景会很有帮助——这样,View 本身就不会像GeometryReader 在前景中那样增长。我从https://***.com/a/59733037/560942借了GeometryReader

删除GeometryReaders 后,您可以使用Spacer 将另一个VStacks 推到屏幕顶部。

struct GeometryGetter: View 
    @Binding var rect: CGRect

    var body: some View 
        GeometryReader  (g) -> Path in
            print("width: \(g.size.width), height: \(g.size.height)")
            DispatchQueue.main.async 
                self.rect = g.frame(in: .global)
            
            return Path() // could be some other dummy view
        
    


struct Post: View 
    @State private var rect1: CGRect = CGRect()
    
    var body: some View 
        HStack(alignment: .top, spacing: 0) 
            Spacer()
            VStack(alignment: .leading) 
                NameAndConnection()
                Description()
                    .padding(.top, 1.0)
            .frame(width: rect1.width * 0.75)
        
        .background(GeometryGetter(rect: $rect1))
        .border(Color.green)
    




struct ContentView: View 
    var body: some View 
            VStack() 
                Post()
                Post()
                Post()
                Spacer()
            
    

【讨论】:

@JohnSorensen 回答了你的问题还是你觉得它有帮助?

以上是关于Swiftui 将 VStack 子项高度调整为内容高度的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中动态调整可垂直滚动的 VStack 中的一行中的项目数?

带有灵活 Spacer 的 SwiftUI VStack

如何将 VStack 拆分为两个子视图,第二个子视图的高度是第一个子视图的两倍?

使用“Vstack”将图像大小调整为屏幕宽度,同时保持纵横比

是否可以在 Swift UI 中获得 VStack 的计算“最小”高度

SwiftUI:将视图与 VStack 中另一个视图的前缘和后缘对齐