Marcos Aba
Marcos Aba

Reputation: 111

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

Upvotes: 6

Views: 4088

Answers (2)

Asperi
Asperi

Reputation: 257889

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

Upvotes: 7

kdion4891
kdion4891

Reputation: 1267

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

Upvotes: 0

Related Questions