swiftUI 中的选取器正在从 Firestore 中选择文档 ID 而不是文档字段

Posted

技术标签:

【中文标题】swiftUI 中的选取器正在从 Firestore 中选择文档 ID 而不是文档字段【英文标题】:Picker in swiftUI is selecting document ID instead of document field from Firestore 【发布时间】:2020-11-09 00:47:37 【问题描述】:

所以我想要做的是在 swiftui 的表单中使用选择器中的 firebase 集合,但是当我选择我想要的运动时,该运动的文档 ID 会保存到我的变量中。

所以这是我的观点,我有选择器。

struct ContentView: View 
    @ObservedObject var sportsObserved = sportsObserver()
    
    @State private var sport = ""

    var body: some View 
        VStack
            Form                 
                Picker(selection: $sport, label: Text("Sport")) 
                    ForEach(self.sportsObserved.sports)  i in
                        Text(i.sportName)
                    
                
                Text("You selected \(sport)")
            
        

    

这些是我的 Firestore 文档的字段。

struct datatype3: Identifiable
    
    var id : String
    var sportName: String
    var eventCount: Int

这是我的数据库可观察对象,它不是必需的,但我将其包括在内,以防有人需要它来完全重现我遇到的错误。

class sportsObserver: ObservableObject
    @Published var sports = [datatype3]()
    init() 
        let db = Firestore.firestore()
        db.collection("sports").addSnapshotListener (snap, err) in
            
            if err != nil 
                print((err?.localizedDescription)!)
                return
            
            for i in snap!.documentChanges
                
                if i.type == .added 
                    
                    let id = i.document.documentID
                    let sportName = i.document.get("sportName") as! String
                    let eventCount = i.document.get("eventCount") as! Int
                    
                    
                    self.sports.append(datatype3(id: id, sportName: sportName, eventCount: eventCount))
                
                
                if i.type == .removed 
                  
                     let id = i.document.documentID
                    
                    for j in 0..<self.sports.count
                        
                        if self.sports[j].id == id
                            self.sports.remove(at: j)
                            return
                        
                    
                
                
                if i.type == .modified 
                    let id = i.document.documentID
                    let sportName = i.document.get("sportName") as! String
                    let eventCount = i.document.get("eventCount") as! Int


                    for j in 0..<self.sports.count

                        if self.sports[j].id == id
                            self.sports[j].sportName = sportName
                            self.sports[j].eventCount = eventCount

                            return
                        
                    
                
            
        
    

当我选择“篮球”时,结果如下:

正如您所见,Basketball 的文档 ID 在我的数据库中设置为 12Basketball,这不能简单地更改为“Basketball”,因为我在构建数据库时必须考虑其他事项。

我希望变量“sport”存储作为运动名称的“篮球”,而不是作为 documentID 的“12Basketball”。

这是我想出的解决方法,如果有人能告诉我一个更好的方法,我仍然会很高兴,因为这种方法很笨重。

.onAppear 
            for i in sportsObserved.sports 
                if sportID == i.id 
                    sport = i.sportName
                
            
Picker(selection: $sportID, label: Text("Sport")) 
                    ForEach(self.sportsObserved.sports)  i in
                        Text(i.sportName).tag(i.id)
                    
                

【问题讨论】:

【参考方案1】:

将修复发布为社区 Wiki 以提高知名度:

.onAppear 
            for i in sportsObserved.sports 
                if sportID == i.id 
                    sport = i.sportName
                
            
Picker(selection: $sportID, label: Text("Sport")) 
                    ForEach(self.sportsObserved.sports)  i in
                        Text(i.sportName).tag(i.id)
                    
                

【讨论】:

以上是关于swiftUI 中的选取器正在从 Firestore 中选择文档 ID 而不是文档字段的主要内容,如果未能解决你的问题,请参考以下文章

选择器中的 SwiftUI 和枚举

SwiftUI 中的选取器委托滚动方法

如何正确处理更新视图中的选取器(SwiftUI)

SwiftUI:选取器不会更新同一视图中的文本

SwiftUI:将选取器选择设置为动态数组中的最后一个

SwiftUI 2 .onChange() 中的选取器不会更改 UINavigationBar.appearance()