带有Cloud Firestore的SwiftUI Picker [英] SwiftUI Picker with Cloud Firestore

查看:32
本文介绍了带有Cloud Firestore的SwiftUI Picker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我是否能够在这方面获得一些帮助,我一直在尝试使事情正常运行并能够将Firestore数据传递到选择器视图中,但是我无法在选定"区域中选择要查看的数据.我已经添加了代码和Firestore设置.

谢谢.

 导入SwiftUI导入Firebasestruct SchoolDetailsView:查看{@ObservedObject var schoolData = getSchoolData()@State var selectedSchool:字符串!var body:some View {VStack {形式 {部分 {Picker(选择:$ selectedSchool,标签:Text(学校名称")){ForEach(self.schoolData.datas){i in文本(self.schoolData.datas.count!= 0?i.name:没有可用的学校").tag(i.name)}}文字(所选学校:\(selectedSchool)")}} .navigationBarTitle(选择您的学校")}}}struct SchoolPicker_Previews:PreviewProvider {静态var预览:某些视图{SchoolDetailsView()}}类getSchoolData:ObservableObject {@已发布的var数据= [schoolName]()在里面() {让db = Firestore.firestore()db.collection(学校名称").addSnapshotListener {(snap,err)在如果err!= nil {打印((err?.localizedDescription)!)返回}为我迅速!.documentChanges {设id = i.document.documentID让名称= i.document.get(名称")为!细绳self.datas.append(schoolName(id:id,名称:名称))}}}}struct schoolName:可识别的{var id:字符串var名称:字符串} 

最后,作为使用SwiftUI的默认列表视图选择器样式的任何人的补充说明,必须将其封装在视图层次结构内某处的NavigationView中.当我第一次开始使用它们时,这让我大跌眼镜:)

I was wondering whether I was able to get some help on this one, I've been trying a while to get things working and functioning properly and have been able to pass the Firestore data into the picker view, but I'm unable to select the data to view in the 'selected' area. I have added my code and my Firestore setup.

Thanks in advance.

import SwiftUI
import Firebase

struct SchoolDetailsView: View {
    
    @ObservedObject var schoolData = getSchoolData()
    @State var selectedSchool: String!

    var body: some View {
        VStack {
            Form {
                Section {
                    Picker(selection: $selectedSchool, label: Text("School Name")) {
                        ForEach(self.schoolData.datas) {i in
                            Text(self.schoolData.datas.count != 0 ? i.name : "No Schools Available").tag(i.name)

                        }
                    }
                    Text("Selected School: \(selectedSchool)")
                }
            }.navigationBarTitle("Select your school")

        }
    }
}

struct SchoolPicker_Previews: PreviewProvider {
    static var previews: some View {
        SchoolDetailsView()
    }
}

class getSchoolData : ObservableObject{
    
    @Published var datas = [schoolName]()
    
    init() {
        
        let db = Firestore.firestore()
        
        db.collection("School Name").addSnapshotListener { (snap, err) in
            
            if err != nil{
                
                print((err?.localizedDescription)!)
                return
            }
            
            for i in snap!.documentChanges{
                
                let id = i.document.documentID
                let name = i.document.get("Name") as! String
                
                self.datas.append(schoolName(id: id, name: name))
            }
        }
    }
}

struct schoolName : Identifiable {
    
    var id : String
    var name : String
}

Firestore Setup Image

解决方案

To solve the issue with the code above the you can cast the tag to be the same type as the selectedSchool variable. This should then allow it to be selectable and is also safer as it uses optionals and allows the picker to be initially set to nil.

Example Code:

struct SchoolDetailsView: View {
    
    @ObservedObject var schoolData = getSchoolData()
    @State var selectedSchool: String?

    var body: some View {
        NavigationView {
            VStack {
                Form {
                    Section {
                        Picker(selection: $selectedSchool, label: Text("School Name")) {
                            ForEach(self.schoolData.datas.sorted(by: { $0.name < $1.name } )) {i in
                                Text(self.schoolData.datas.count != 0 ? i.name : "No Schools Available").tag(i.name as String?)
                            }
                        }
                        Text("Selected School: \(selectedSchool ?? "No School Selected")")
                    }
                }.navigationBarTitle("Select your school")
            }
        }
    }
}

As an alternative to the example above, you could also change the selectedSchool variable to be a schoolName type and cast the tag to be schoolName and this will also work. The only caveat with this approach is that the schoolName type must conform to the Hashable protocol.

Example Alternative Code:

struct schoolName: Identifiable, Hashable {
    var id: String
    var name: String
}

struct SchoolDetailsView: View {
    
    @ObservedObject var schoolData = getSchoolData()
    @State var selectedSchool: schoolName?

    var body: some View {
        NavigationView {
            VStack {
                Form {
                    Section {
                        Picker(selection: $selectedSchool, label: Text("School Name")) {
                            ForEach(self.schoolData.datas.sorted(by: { $0.name < $1.name } )) {i in
                                Text(self.schoolData.datas.count != 0 ? i.name : "No Schools Available").tag(i as schoolName?)
                            }
                        }
                        Text("Selected School: \(selectedSchool?.name ?? "No School Selected")")
                    }
                }.navigationBarTitle("Select your school")
            }
        }
    }
}

Either of these code examples should result in a working picker as follows:

Finally, as a side note for anyone when working with SwiftUI's default list view picker style, it must be enclosed within a NavigationView somewhere within the view hierarchy. This tripped me up when I first started using them :)

这篇关于带有Cloud Firestore的SwiftUI Picker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆