Search code examples
swiftswiftuiswiftui-picker

Selecting in Picker does not change selection


I am trying to display the picker and the selected emoji on the screen.
Here is the ContentView:

struct ContentView : View {
    @StateObject private var viewModel = ContentViewModel()
    @State private var selectedEmoji = Emoji(id: 1, name: "heart", uniqueString: "\u{1F496}")
    
    var body: some View {
        VStack {
            Text(selectedEmoji.uniqueString)
                .font(.system(size: 150))
            
            Picker("Emoji Picker", selection: $selectedEmoji) {
                ForEach(viewModel.emojis) { emoji in
                    Text(emoji.uniqueString)
                }
            }.pickerStyle(.segmented)
            
        }.onAppear {
            viewModel.getAllEmojis()
        }
    }
}

Model:

struct Emoji: Identifiable, Hashable {
    let id: Int
    let name, uniqueString: String
}

ViewModel:

class ContentViewModel : ObservableObject {
    @Published var emojis: [Emoji] = []
    
    func getAllEmojis() {
        let emoji1 = Emoji(id: 1, name: "heart", uniqueString: "\u{1F496}")
        let emoji2 = Emoji(id: 2, name: "black heart", uniqueString: "\u{2665}")
        let emoji3 = Emoji(id: 3, name: "dollarSign", uniqueString: "\u{24}")
        let emoji4 = Emoji(id: 4, name: "boom", uniqueString: "\u{2663}")
        emojis = [emoji1, emoji2, emoji3, emoji4]
    }
}

When selecting a different emoji from the picker, the value in selectedEmoji doesn't change. The UI in the first Text always shows \u{1F496}.

How can I fix it?


Solution

  • try adding a .tag, such as:

    Picker("Emoji Picker", selection: $selectedEmoji) {
        ForEach(viewModel.emojis) { emoji in
            Text(emoji.uniqueString)
               .tag(emoji)  // <--- here
        }
    }.pickerStyle(.segmented)