SwiftUI Picker在点击时不改变选择

Posted

技术标签:

【中文标题】SwiftUI Picker在点击时不改变选择【英文标题】:SwiftUI Picker not changing selection when tapped 【发布时间】:2021-03-27 10:15:18 【问题描述】:

这是我的对象列表:

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"),
]

在我看来,我的Picker

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

点击时,我的Picker 成功显示列表/菜单中的所有gameTypes 项目。但是,当我点击该列表中的某个项目时,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
    

【问题讨论】:

什么是游戏类型?你能显示它的代码吗? 抱歉,添加到编辑@TusharSharma 【参考方案1】:

这是因为 GameType 和 Tag 类型不同。并且在选择时,swift 无法将Int 分配给GameType 类型。 只需将您的标签更改为type 而不是type.id,一切都会正常工作。 示例

HStack 
         Picker("\(gameType.text)", selection: $gameType) 
            ForEach(gameTypes, id: \.id)  type in
                 Text("\(type.text)").tag(type)
            
         
         .pickerStyle(MenuPickerStyle())
     

【讨论】:

【参考方案2】:

这里有救命之恩,需要用struc:



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

【讨论】:

以上是关于SwiftUI Picker在点击时不改变选择的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI Segmented Picker 在点击时不会切换

SwiftUI:添加元素时选择器内容未刷新

SwiftUI 中的选择器选择和翻译冲突

未显示来自 JSON 的 SwiftUI Picker 数据

在 SwiftUI 中,我如何知道 Picker 选择何时更改?为啥 didSet 不起作用?

选择后的 SwiftUI Picker 动画错误