如何在 SwiftUI 中根据其子级高度设置 GeometryReader 高度?

Posted

技术标签:

【中文标题】如何在 SwiftUI 中根据其子级高度设置 GeometryReader 高度?【英文标题】:How to set GeometryReader height according to its children height in SwiftUI? 【发布时间】:2019-10-18 15:14:27 【问题描述】:

在我的 SwiftUI 应用程序中,我有一个获得全屏高度的 VStack (VStack 1) 容器。在这个 VStack 中,我有另一个 VStack(VStack 2),它根据其子级(文本)获取高度,我想把它放在这个父级(VStack 1)的底部。在 VStack 2 上,我需要放置一个 GeometryReader 来获取 VStack (VStack 2) 的高度。问题是 GeometryReader 会自动获得全屏高度。所以 VStack 2 被放置在屏幕的中间。这不是我想要的。不知道能不能把GeometryReader的高度设置成和VStack 2一样的高度?

我的测试代码:

import SwiftUI

struct ContentView: View 
  var body: some View 
    VStack 
      GeometryReader  geometry in
        VStack 
           Text("Text n°1")
           Text("Text n°2")
           Text("Text n°3")
           Text("Text n°4")
        
        .border(Color(.red))
      
      .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: nil, alignment: .bottom)
      .border(Color(.black))
    
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .bottom)
  

结果:

我想要的:

感谢您的帮助。

【问题讨论】:

【参考方案1】:

以下是使用GeometryReader时将子视图高度设置为父视图

import SwiftUI

struct ContentView: View 
    
    @State private var totalHeight = CGFloat(100) // no matter - just for static Preview !!
    
    var body: some View 
        HStack(alignment:.top) 
            Text("Title 1")
            GeometryReader  geo in
                VStack(spacing: 10) 
                    Text("Subtitle 1")
                        .frame(maxWidth: .infinity)
                    Text("Subtitle 2")
                        .frame(maxWidth: .infinity)
                    Text("Subtitle 3")
                        .frame(maxWidth: .infinity)
                
                .background(Color.blue)
                .frame(width: geo.size.width * 0.6)
                .background(GeometryReader gp -> Color in
                    DispatchQueue.main.async 
                        // update on next cycle with calculated height of ZStack !!!
                        self.totalHeight = gp.size.height
                    
                    return Color.clear
                )
            
            .background(Color.yellow)
        
        .frame(maxWidth: .infinity)
        .frame(height: totalHeight)
        .background(Color.green)
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

参考 - https://***.com/a/61315678/815864

【讨论】:

DispatchQueue.main.async 会导致绘图循环吗?【参考方案2】:

我认为您使用 GeometryReader 过于复杂了。您是否尝试过仅使用Spacer()

struct ContentView: View 
    var body: some View 
        VStack 
            Text("Haha")
            Spacer()
            VStack 
                Text("1")
                Text("2")
                Text("3")
            
        
    

【讨论】:

我需要使用GeometryReader来获取第二个VStack的高度值

以上是关于如何在 SwiftUI 中根据其子级高度设置 GeometryReader 高度?的主要内容,如果未能解决你的问题,请参考以下文章

如何限制可拖动滚动表根据其子高度在颤动中获取高度?

如何根据 Flutter 中的子项更改容器的高度?

SwiftUI:如何找到图像的高度并使用它来设置框架的大小

在 SwiftUI 中根据文本高度自动调整视图高度

如何计算 SwiftUI 中的标签栏高度?

根据显示弹性框中的子级设置父级高度/宽度