【问题标题】:Swift UI adjust VStack children height to content heightSwiftui 将 VStack 子项高度调整为内容高度
【发布时间】: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——到目前为止您发布的内容实际上无法使用任何人,因为它依赖于自定义类型。

标签: swift layout swiftui vstack hstack


【解决方案1】:

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

当您必须使用它时,通常测量View 的背景会很有帮助——这样,View 本身就不会像GeometryReader 在前景中那样增长。我从https://stackoverflow.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 回答了你的问题还是你觉得它有帮助?
猜你喜欢
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2017-07-15
相关资源
最近更新 更多