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:
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("