1

Here is my list of objects:

let gameTypes = [
    GameType(id: "generalKnowledge", text: "❓ General Knowledge"),
    GameType(id: "geography", text: "🌎 Geography"),
    GameType(id: "music", text: "🎤 Music"),
    GameType(id: "sport", text: "⚽️ Sport"),
    GameType(id: "technology", text: "💻 Technology"),
    GameType(id: "movies", text: "📺 Movies & TV"),
]

And my Picker in my view:

@State var gameType: GameType = gameTypes[0]

var body: some View {
    NavigationView {
        VStack {
            // Create game
            HStack {
                Picker("\(gameType.text)", selection: $gameType) {
                    ForEach(gameTypes, id: \.id){ type in
                        Text("\(type.text)").tag("\(type.id)")
                    }
                }
                .pickerStyle(MenuPickerStyle())

My Picker successfully shows all gameTypes items in a list/menu when tapped. However when I tap an item in that list, gameType does not update.

Any idea why?

EDIT:

GameType

class GameType: Hashable, Equatable {
    let id: String
    let text: String
    
    init(id: String, text: String) {
        self.id = id
        self.text = text
    }
    
    // Conform to Hashable
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    // Conform to Equatable (players will not be the same)
    static func == (lhs: GameType, rhs: GameType) -> Bool {
        return false
    }
}
2
  • what is GameType? Can you show code for it? Commented Mar 27, 2021 at 12:07
  • Sorry, added in edit @TusharSharma Commented Mar 27, 2021 at 12:10

2 Answers 2

1

This is because the GameType and Tag types are different. And when selecting, swift does not work to assign an Int to the GameType type. Just change your tag to the type instead of type.id and everything will work. Example

HStack {
         Picker("\(gameType.text)", selection: $gameType) {
            ForEach(gameTypes, id: \.id) { type in
                 Text("\(type.text)").tag(type)
            }
         }
         .pickerStyle(MenuPickerStyle())
     }
Sign up to request clarification or add additional context in comments.

Comments

0

here is a salvation, you need to use struc:


enter image description here


struct GameType: Hashable, Identifiable, Equatable {
    
    let id: String
    let text: String
    
    init(id: String, text: String) {
        self.id = id
        self.text = text
    }
    
    static func == (lhs: GameType, rhs: GameType) -> Bool {
        return lhs.id == rhs.id
    }
}


let gameTypes = [
    GameType(id: "generalKnowledge", text: "❓ General Knowledge"),
    GameType(id: "geography", text: "🌎 Geography"),
    GameType(id: "music", text: "🎤 Music"),
    GameType(id: "sport", text: "⚽️ Sport"),
    GameType(id: "technology", text: "💻 Technology"),
    GameType(id: "movies", text: "📺 Movies & TV"),
]

import SwiftUI

struct ContentView: View {

    @State var gameTypeSelected: String = gameTypes[3].id
    
    var body: some View {

        Picker(selection: $gameTypeSelected, label: Text("")) {
  
            ForEach(gameTypes, id: \.id) { item in
                
                Text(item.text).id(item.id)
            }

        }
        
        Text("You selected: " + gameTypeSelected).bold()
        
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.