首页 > 解决方案 > 当 Firebase 中的数据发生变化时更新视图错误

问题描述

这是我启动应用程序的时候,它看起来没问题 这是我从 firebase 更改一些数据时,你可以看到一些数据没有以正确的方式排列,一些矩形是双倍的我目前正在处理我需要的这个项目从 Firebase 读取数据并根据更改更新我的视图。每次我的数据在 firebase 上发生变化时,我的视图都会以奇怪的方式出现错误。

这是我的学生课

struct Student : Identifiable {
    var id : String
    var name : String
    var surname : String
    var isAbsent : Bool
    var isBathroom : Bool
}

在这里,我从 firebase 获取数据并发布以获取所有其他视图的数据

class getStudents: ObservableObject {

    @Published var datas = [Student]()

    init() {
        let db = Firestore.firestore()
        let classRef = db.collection("5SA")

        classRef.order(by: "surname").addSnapshotListener {(snap,error) in
            if error != nil{
                print((error?.localizedDescription)!)
                return
            }


            for i in snap!.documentChanges{

                let id = i.document.documentID
                let name = i.document.get("name")as! String
                let surname = i.document.get("surname") as! String
                let isAbsent = i.document.get("absent") as! Bool
                let isBathroom = i.document.get("bathroom") as! Bool


                self.datas.append(Student(id: id, name: name, surname: surname, isAbsent: isAbsent, isBathroom: isBathroom))

              if i.type == .modified{
                    let isAbsent = i.document.get("absent") as! Bool
                    let isBathroom = i.document.get("bathroom") as! Bool
                    for j in 0..<self.datas.count{

                        if self.datas[j].id == id{

                            self.datas[j].isAbsent = isAbsent
                            self.datas[j].isBathroom = isBathroom
                        }
                    }
                }

            }

    }
}
}

这是我的看法。除了 iPad 模拟器上的风景之外,每次都有错误。我想要实现的是像类应用程序一样创建。有学生缺席的地方,在厕所里或在场的地方。我想向每个学生展示一个带有他名字的矩形,并在每次我的火基地上的布尔值发生变化时更改矩形的颜色(isAbsent,isBathroom)。但是,当我尝试更改 firebase 上的值时,矩形会成倍增加并产生奇怪的想法。

struct ContentView: View {

    @ObservedObject var students = getStudents()

    var body: some View {
        NavigationView{

            VStack{
                ScrollView{
                Text("Menu")
                Menu().background(Color.white)
                Text("Future verifiche")
                HStack{
                    ScrollView(.horizontal, showsIndicators: false){
                        RoundedRectangle(cornerRadius: 20).frame(width:300,height: 300).foregroundColor(.white).overlay(Text("V. Matematica"))
                    }
                }
                Text("Oggi")
                HStack{
                    Spacer()
                    Text("Assenti ")
                    Spacer()
                    Text("In bagno")
                    Spacer()
                    Text("Presenti")
                    Spacer()
                }
                HStack{
                    Spacer()

                    ScrollView{
                        ForEach(students.datas,id: \.id){student in
                            VStack(spacing: 15){
                                if student.isAbsent{
                                    RoundedRectangle(cornerRadius: 20).frame(width:200,height: 100).foregroundColor(self.getColor(isAbsent: student.isAbsent, isBathroom: student.isBathroom)).overlay(Text(student.name))
                                }
                            }
                        }
                    }
                    Spacer()
                    ScrollView{
                        ForEach(students.datas,id: \.id){student in
                            VStack(spacing: 15){
                                if student.isBathroom{
                                    RoundedRectangle(cornerRadius: 20).frame(width:200,height: 100).foregroundColor(self.getColor(isAbsent: student.isAbsent, isBathroom: student.isBathroom)).overlay(Text(student.name))
                                }
                            }
                        }
                    }
                    Spacer()
                    ScrollView{
                        ForEach(students.datas,id: \.id){student in
                            VStack(spacing: 15){
                                if !student.isAbsent && !student.isBathroom{
                                    RoundedRectangle(cornerRadius: 20).frame(width:200,height: 100).foregroundColor(self.getColor(isAbsent: student.isAbsent, isBathroom: student.isBathroom)).overlay(Text(student.name))
                                }
                            }
                        }
                    }
                    Spacer()
                }
            }
            }.navigationBarTitle("Classe 5SA",displayMode: .inline)
        }.navigationViewStyle(StackNavigationViewStyle())

    }
    func getColor(isAbsent: Bool, isBathroom : Bool) -> Color {
        if isAbsent{
            return Color.red
        }
        if isBathroom{
            return Color.blue
        }
        return Color.green
    }
}


struct Menu : View {

    var body : some View{
        HStack{
            NavigationLink(destination: Studenti()){

                RoundedRectangle(cornerRadius: 30).frame(width: 150,height: 150).foregroundColor(.red).opacity(0.5).overlay(Text("Studenti").foregroundColor(.black))

            }
            NavigationLink(destination: Text("Overview")){

            RoundedRectangle(cornerRadius: 30).frame(width: 150,height: 150).foregroundColor(.green).opacity(0.5).overlay(Text("Overview").foregroundColor(.black))

            }
            NavigationLink(destination: Text("Orario")){
            RoundedRectangle(cornerRadius: 30).frame(width: 150,height: 150).foregroundColor(.blue).opacity(0.5).overlay(Text("Orario").foregroundColor(.black))
            }

            NavigationLink(destination: Text("Calendario")){

            RoundedRectangle(cornerRadius: 30).frame(width: 150,height: 150).foregroundColor(.orange).opacity(0.5).overlay(Text("Calendario").foregroundColor(.black))

            }
        }
    }
}

struct Studenti : View {
    @ObservedObject var students = getStudents()
    var body : some View {
        ForEach(students.datas,id: \.id){student in
            VStack{
                Rectangle().frame(width:300,height: 150).foregroundColor(self.getColor(isAbsent: student.isAbsent, isBathroom: student.isBathroom)).overlay(Text(student.name))
            }
        }
    }
    func getColor(isAbsent: Bool, isBathroom : Bool) -> Color {
        if isAbsent{
            return Color.red
        }
        if isBathroom{
            return Color.blue
        }
        return Color.green
    }
}

标签: iosswiftfirebasegoogle-cloud-firestoreswiftui

解决方案


推荐阅读