2

In a simple test project at Github I am trying to display a Menu with 3 languages and the flags to allow users select the localization:

struct ContentView: View {
    // ...some Core Data related code skipped...
    
    let labels = [
        "en" : " EN",
        "de" : " DE",
        "ru" : " RU"
    ]
    
    @AppStorage("language") var language:String = "en"

    var body: some View {
        VStack(alignment: .trailing) {

            Menu(language) {
                Button(" EN", action: { language = "en" })
                Button(" DE", action: { language = "de" })
                Button(" RU", action: { language = "ru" })
            }.padding()
            
            List {
                ForEach(topEntities) { top in
                    TopRow(topEntity: top)
                }
            }
        }.environment(\.locale, .init(identifier: language))
    }
}

The above code seems to work ok, but has one cosmetic problem: the Menu displays the selected language a simple string "en" (or "de", or "ru"):

screenshot

Being a Swift and SwiftUI newbie I do not understand, how to set the label to the nicer string, i.e. to the selected language and flag, like " EN". Please help

Alexander Farber
  • 21,519
  • 75
  • 241
  • 416

1 Answers1

2

You can get the nice string from your labels dictionary. Here is the working version:

Menu(labels[language] ?? "Unknown") {
    Button(" EN", action: { language = "en" })
    Button(" DE", action: { language = "de" })
    Button(" RU", action: { language = "ru" })
}.padding()

I just replaced language with labels[language] ?? "Unknown".

George
  • 25,988
  • 10
  • 79
  • 133
  • I think logically we can use a force unwrap`Menu(labels[language]!)` to make sure you don't end up with an `unknown` language – cedricbahirwe Jun 12 '21 at 06:57
  • 1
    @cedricbahirwe Ideally it should _never_ be unknown. However since we can’t guarantee it since the language is set as a string (and any string could be set), I thought this would be a bit safer. – George Jun 12 '21 at 11:40