观察对象更改时,Swift View 不更新
Posted
技术标签:
【中文标题】观察对象更改时,Swift View 不更新【英文标题】:Swift View not updating when Observed Object changes 【发布时间】:2020-05-02 13:45:26 【问题描述】:我有一些这样的代码:
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
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
现在的问题是,我可以删除 2View 中的项目。然后也显示了这一点,并且我实现了它也删除数据库中的项目的功能。 所以数据库数据被改变了,但在我通过例如刷新它之前,这不会显示在 3View 中。重新审视它。
我不知道是什么原因。也许我对 @Published
和 ObservedObject
有错误的理解?
【问题讨论】:
您分配了 dbContent 吗?dbContent
被我在从数据库中获取数据时创建的自定义对象“覆盖”。也许这就是错误所在?我在这个方法中有一个snapshotListener,这个方法的目标是将新创建的对象分配给dbContent
。像这样工作吗?
【参考方案1】:
@State
表示视图拥有数据并管理状态。尝试在您的子视图中使用@ObservedObject
。这是一个例子:
型号
struct Book: Codable, Identifiable
@DocumentID var id: String?
var title: String
var author: String
var numberOfPages: Int
enum CodingKeys: String, CodingKey
case id
case title
case author
case numberOfPages = "pages"
视图模型
class BooksViewModel: ObservableObject
@Published var books = [Book]()
private var db = Firestore.firestore()
private var listenerRegistration: ListenerRegistration?
private var cancellables = Set<AnyCancellable>()
init()
fetchData()
deinit
unregister()
func unregister()
if listenerRegistration != nil
listenerRegistration?.remove()
func fetchData()
unregister()
listenerRegistration = db.collection("books").addSnapshotListener (querySnapshot, error) in
guard let documents = querySnapshot?.documents else
print("No documents")
return
self.books = documents.compactMap queryDocumentSnapshot -> Book? in
return try? queryDocumentSnapshot.data(as: Book.self)
func deleteBooks(at offsets: IndexSet)
self.books.remove(atOffsets: offsets)
观看次数
import SwiftUI
struct SampleView: View
@ObservedObject var viewModel = BooksViewModel()
var body: some View
VStack
InnerListView1(viewModel: viewModel)
InnerListView2(viewModel: viewModel)
struct InnerListView1: View
@ObservedObject var viewModel: BooksViewModel
var body: some View
List
ForEach(viewModel.books) book in
VStack(alignment: .leading)
Text(book.title)
.font(.headline)
Text(book.author)
.font(.subheadline)
Text("\(book.numberOfPages) pages")
.font(.subheadline)
.onDelete indexSet in
self.viewModel.deleteBooks(at: indexSet)
struct InnerListView2: View
@ObservedObject var viewModel: BooksViewModel
var body: some View
List(viewModel.books) book in
VStack(alignment: .leading)
Text(book.title)
.font(.headline)
Text(book.author)
.font(.subheadline)
Text("\(book.numberOfPages) pages")
.font(.subheadline)
我在尝试重现您的问题时注意到的一件事:如果您使用的是 CodingKeys
(只有在 Firestore 文档上的属性名称与 Swift 结构上的属性名称不同时才需要这样做),您需要确保id
也包括在内。否则,id
将为 nil,这将导致 List
视图无法区分项目。
【讨论】:
遗憾的是,这并没有成功。但是感谢您的努力! @Simon,我已经扩展了示例 - 请再试一次。我刚刚尝试过,它按预期工作。以上是关于观察对象更改时,Swift View 不更新的主要内容,如果未能解决你的问题,请参考以下文章
Swift Firestore 来自查询的自定义对象,同时使用 snapshotListener 监听实时更新
SwiftUI - 从 Swift 类启动的可观察对象不会更新 ContentView() 上的 @ObservedObject