Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set GeometryReader height according to its children height in SwiftUI?

Tags:

swift

swiftui

In my SwiftUI application, I have a VStack (VStack 1) container that get full screen height. Inside this VStack, I have an other VStack (VStack 2) that get height according to its childrens (Text), and I want to put it at the bottom of this parent (VStack 1). On the VStack 2, I need to put a GeometryReader to get the height of VStack (VStack 2). The problem is that the GeometryReader get automaticaly full screen height. So the VStack 2 is placed on the middle of the screen. It's not that I want. I don't know if I can set the height of the GeometryReader with the same height of the VStack 2?

My test code:

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

The result:

Screenshot

That I want:

Result I need

Thank you for your help.

like image 543
Guillaume Avatar asked Oct 18 '19 15:10

Guillaume


1 Answers

Following is to set child view height to parent view when using GeometryReader

enter image description here

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

Ref - https://stackoverflow.com/a/61315678/815864

like image 166
Thein Avatar answered Oct 02 '22 22:10

Thein