观察到的对象更改时,Swift视图不更新
我有一些这样的代码:观察到的对象更改时,Swift视图不更新,swift,firebase,google-cloud-firestore,swiftui,Swift,Firebase,Google Cloud Firestore,Swiftui,我有一些这样的代码: class Data: ObservableObject { @Published var data = dbContent init(){ let db = Firestore.firestore() db.collection("collection").document(userID).addSnapshotListener { //getting data from DB and storing them as objects by appendi
class Data: ObservableObject {
@Published var data = dbContent
init(){
let db = Firestore.firestore()
db.collection("collection").document(userID).addSnapshotListener {
//getting data from DB and storing them as objects by appending them to data
}
}
}
现在的问题是,我可以在2View中删除该项。然后还显示了这一点,我实现了删除数据库中项目的功能。
因此,DB数据会被更改,但在我通过重新访问等方式刷新它之前,它不会显示在3View中
我不知道原因是什么。也许我对
@已发布的和观察对象的理解有误 @State
表示视图拥有数据并管理状态。在子视图中也尝试使用@ObservedObject
。以下是一个例子:
型号
struct Book:可编码、可识别{
@DocumentID变量id:String?
变量标题:字符串
var作者:String
var numberOfPages:Int
枚举编码键:字符串,编码键{
病例id
案件名称
案例作者
案例编号pages=“页数”
}
}
视图模型
class BooksViewModel:ObserveObject{
@已发布的var books=[Book]()
private var db=Firestore.Firestore()
私有var listenerRegistration:listenerRegistration?
private var cancelables=Set()
init(){
fetchData()
}
脱硝{
注销
}
func unregister(){
如果listenerRegistration!=无{
listenerRegistration?.remove()
}
}
func fetchData(){
注销
listenerRegistration=db.collection(“books”).addSnapshotListener{(querySnapshot,error)在
guard let documents=querySnapshot?.其他文档{
打印(“无文件”)
返回
}
self.books=documents.compactMap{queryDocumentSnapshot->Book?in
返回try?queryDocumentSnapshot.data(as:Book.self)
}
}
}
func deleteBooks(偏移量处:IndexSet){
self.books.remove(原子偏移:偏移)
}
}
视图
导入快捷界面
结构示例视图:视图{
@ObservedObject var viewModel=BooksViewModel()
var body:一些观点{
VStack{
InnerListView1(viewModel:viewModel)
InnerListView2(viewModel:viewModel)
}
}
}
结构InnerListView1:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
名单{
ForEach(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(\(图书编号页)页)
.font(.subheadline)
}
}
.onDelete{indexSet in
self.viewModel.deleteBooks(at:indexSet)
}
}
}
}
结构InnerListView2:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
列表(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(\(图书编号页)页)
.font(.subheadline)
}
}
}
}
在试图重现您的问题时,我注意到一件事:如果您使用的是CodingKeys
(仅当Firestore文档上的属性名称与Swift结构上的属性名称不同时才需要这样做),则需要确保还包括id
。否则,id
将为零,这将导致列表
视图无法区分项目。@State
表示视图拥有数据并管理状态。在子视图中也尝试使用@ObservedObject
。以下是一个例子:
型号
struct Book:可编码、可识别{
@DocumentID变量id:String?
变量标题:字符串
var作者:String
var numberOfPages:Int
枚举编码键:字符串,编码键{
病例id
案件名称
案例作者
案例编号pages=“页数”
}
}
视图模型
class BooksViewModel:ObserveObject{
@已发布的var books=[Book]()
private var db=Firestore.Firestore()
私有var listenerRegistration:listenerRegistration?
private var cancelables=Set()
init(){
fetchData()
}
脱硝{
注销
}
func unregister(){
如果listenerRegistration!=无{
listenerRegistration?.remove()
}
}
func fetchData(){
注销
listenerRegistration=db.collection(“books”).addSnapshotListener{(querySnapshot,error)在
guard let documents=querySnapshot?.其他文档{
打印(“无文件”)
返回
}
self.books=documents.compactMap{queryDocumentSnapshot->Book?in
返回try?queryDocumentSnapshot.data(as:Book.self)
}
}
}
func deleteBooks(偏移量处:IndexSet){
self.books.remove(原子偏移:偏移)
}
}
视图
导入快捷界面
结构示例视图:视图{
@ObservedObject var viewModel=BooksViewModel()
var body:一些观点{
VStack{
InnerListView1(viewModel:viewModel)
InnerListView2(viewModel:viewModel)
}
}
}
结构InnerListView1:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
名单{
ForEach(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(\(图书编号页)页)
.font(.subheadline)
}
}
.onDelete{indexSet in
self.viewModel.deleteBooks(at:indexSet)
}
}
}
}
结构InnerListView2:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
列表(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(“\(book.numberOfPages)页
struct 1View: View {
@ObservedObject var myData: Data = Data()
var body: some View {
2View(myData: self.myData)
3View(myData: self.myData)
}
}
struct 2View: View {
@State var myData: Data
var body: some View {
List(){
ForEach(data.count){ data in
Text(data)
}.onDelete(perform: deleteData) //Deletes the item
}
}
}
struct 3View: View {
@State var myData: Data
var body: some View {
List(){
ForEach(data.count){ data in
Text(data)
}.onDelete(perform: deleteData) //Deletes the item
}
}
}