skip to Main Content

I have a dropdown menu that acts a little weird, see here.

The text updates step by step, not instantaneously, and it quivers for a little bit after being updated.

Here is the relevant code:

The state variables used

@State private var gender = ""
@State private var birthDate = Date.now
@State private var formattedDate = ""
@State private var genderMenuTitle = "Gender"

The Form where the dropdown menu lies:

Form {
    Section(header: Text("Gender")) {
        Menu(genderMenuTitle) {
            Button (action: {
                gender = "F"
                genderMenuTitle = "Female"
                print(gender)
            }, label: {
                Text("Female")
            })
            Button (action: {
                gender = "M"
                genderMenuTitle = "Male"
                print(gender)
            }, label: {
                Text("Male")
            })
            Button (action: {
                gender = "O"
                genderMenuTitle = "Other"
                print(gender)
            }, label: {
                Text("Other")
            })
            Button (action: {
                gender = "?"
                genderMenuTitle = "Rather not say"
                print(gender)
            }, label: {
                Text("Rather not say")
            })
      }
}

Why is this happening?

2

Answers


  1. Because you’re manually updating your view every-time a user clicks the button, you can make this process smoother by using a withAnimation closure.

    withAnimation {
    
    gender = "F"
    genderMenuTitle = "Female"
    
    }
    

    But I would recommend you to just use a picker instead.

    struct ContentView: View {
        
        @State private var gender = "Male"
        
        var genderOptions = [
            "Female",
            "Male",
            "Other",
            "Rather not say"
        ]
        
        var body: some View {
            VStack {
                Form {
                    Section(header: Text("Gender")) {
                        Picker("", selection: $gender) {
                            ForEach(genderOptions, id: .self) { key in
                                Text(key)
                                    .tag(key)
                            }
                        }
                        .labelsHidden()
                        .pickerStyle(.menu)
                    }
                }
            }
        }
    }
    
    Login or Signup to reply.
  2. It isn’t you particularly, but if you have a Menu where you change the title, which is typical, don’t use the initializer init(_ titleKey: LocalizedStringKey, @ViewBuilder content: () -> Content) where Label == Text rather use init(@ViewBuilder content: () -> Content, @ViewBuilder label: () -> Label) like below. I also simplified things by using an enum to reduce the amount of state tracking:

    struct WeirdMenuView: View {
        
        @State private var gender: Gender? = nil
    
        var body: some View {
            Form {
                Section(header: Text("Gender")) {
                    Menu {
                        Button (action: {
                            gender = .female
                            print(gender ?? "")
                        }, label: {
                            Text("Female")
                        })
                        Button (action: {
                            gender = .male
                            print(gender ?? "")
                        }, label: {
                            Text("Male")
                        })
                        Button (action: {
                            gender = .other
                            print(gender ?? "")
                        }, label: {
                            Text("Other")
                        })
                        Button {
                            gender = .ratherNotSay
                            print(gender ?? "")
                        } label: {
                            Text("Rather not say")
                        }
    
                    } label: {
                        // Use an actual view here. *****
                        HStack {
                            Text(gender?.rawValue.capitalized ?? "Gender")
                            Spacer()
                        }
                    }
    
                }
            }
        }
    }
    
    enum Gender: String {
        case female = "Female"
        case male = "Male"
        case other = "Other"
        case ratherNotSay = "Rather not say"
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search