Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScrollView causes buggy buttons in SwiftUI

I've been trying to create a form in SwiftUI but because of the limitations using "Form()" I instead chose to create a ScrollView with a ForEach loop that contains a button. When I run the project and I try to click on the buttons it clicks the incorrect one, unless I scroll the view. I am new in SwiftUI and I have not been able to figure it out.

I tried making the ScrollView in different sizes and it doesn't seem to be related

struct DropDown: View {

var datos: [String]
var categoria: String

@State var titulo: String = "Seleccione"
@State var expand = false

var body: some View {

    VStack {
        Text(categoria).fontWeight(.heavy).foregroundColor(.white)
        HStack {
            Text(titulo).fontWeight(.light).foregroundColor(.white)
            Image(systemName: expand ? "chevron.up" : "chevron.down").resizable().frame(width: 10, height: 6).foregroundColor(.white)

        }.onTapGesture {
            self.expand.toggle()
        }

        if expand {
            ScrollView(showsIndicators: true) {
                ForEach(0..<self.datos.count){ nombre in
                    Button(action: {
                        print(self.datos[nombre])
                        self.titulo = self.datos[nombre]
                        self.expand.toggle()
                        diccionarioDatos[self.categoria] = self.titulo
                        print(diccionarioDatos)
                    }) {
                        Text(self.datos[nombre]).foregroundColor(.white)
                    }
                }
            }
            .frame(maxHeight: 150)
            .fixedSize()
        }
    }
    .padding()
    .background(LinearGradient(gradient: .init(colors: [.blue, .green]), startPoint: .top, endPoint: .bottom))
    .cornerRadius(20)
    .animation(.spring())
}

}

I clicked on "2018" under "Modelo" and "2015" got selected for some reason

This is how the dropdown menu looks like

like image 732
Marcos Aba Avatar asked Nov 06 '19 22:11

Marcos Aba


2 Answers

As I tested the observed behaviour is due to order of animatable properties. In your case moving rounding corners into background itself solves the problem.

So instead of

.background(
    LinearGradient(gradient: .init(colors: [.blue, .green]), startPoint: .top, endPoint: .bottom)
)
.cornerRadius(20)

Use

.background(
    LinearGradient(gradient: .init(colors: [.blue, .green]), startPoint: .top, endPoint: .bottom)
        .cornerRadius(20)
)
like image 60
Asperi Avatar answered Nov 11 '22 20:11

Asperi


Consider using .onTapGesture instead of action for the buttons.

Button(action: {}, label: {
    Text(self.datos[nombre]).foregroundColor(.white)
}).onTapGesture{
    print(self.datos[nombre])
    self.titulo = self.datos[nombre]
    self.expand.toggle()
    diccionarioDatos[self.categoria] = self.titulo
    print(diccionarioDatos)
}
like image 43
kdion4891 Avatar answered Nov 11 '22 22:11

kdion4891