Home > Net >  Understanding frame idealHeight, maxHeight in GeometryReader
Understanding frame idealHeight, maxHeight in GeometryReader

Time:12-22

I have 3 buttons displayed in a GeometryReader. I am having trouble understanding how to correctly use .frame(), so that the buttons ideally have a set height (e.g. 60) when they are displayed on devices (iPhone 14) where the GeometryReader height is sufficient for all 3 buttons to fit; otherwise set the height as GeometryReader height*0.3.

My code:

GeometryReader { geometry in
    VStack(alignment: .center) {
        ForEach((0..<3), id: \.self) {i in
            
            Button(action: {
                self.selected = i
            }) {
                VStack {
                    HStack {
                        Text(icons[i])
                            .font(.system(size: 24))
                        Text(buttonNames[i])
                            .font(.system(size: 20))
                    }
                }
                .foregroundColor(.black)
                .frame(maxWidth: UIScreen.main.bounds.width - 88, idealHeight: 60, maxHeight: (geometry.size.height * 0.3), alignment: .leading)
                .padding([.leading, .trailing])
                .background(
                    RoundedRectangle(cornerRadius: 20)
                        .fill(Color.white)
                )
                .overlay( self.selected == i ?
                          RoundedRectangle(cornerRadius: 20)
                    .stroke(LinearGradient(colors: [blue1, blue3], startPoint: .top, endPoint: .bottom), lineWidth: 2)
                          : nil
                )
            }
        }
    }.frame(width: geometry.size.width,
            height: geometry.size.height,
            alignment: .center)
}

Currently, it uses the maxHeight regardless of device. Why is this?

CodePudding user response:

As I understand your goal you don't need a GeometryReader as SwiftUI is taking over a lot of work for you.

You only have to define a maxHeight of 60 for the buttons.

This means that the button frame will try to take a maximum height of 60 pixels, IF they are available. If not, the remaining space will be evenly divided by all views – in your case the three buttons.

I set up a dummy element underneath the buttons, which you can enlarge to "squeeze" the buttons up and see what happens:

enter image description here

struct ContentView: View {
    
    @State private var selected = 0
    @State private var height = 300.0

    var body: some View {
        
        //        GeometryReader { geometry in
        VStack(alignment: .center) {
            ForEach((0..<3), id: \.self) {i in
                
                Button(action: {
                    self.selected = i
                }) {
                    HStack {
                        Text("           
  • Related