【发布时间】:2020-03-17 21:59:03
【问题描述】:
我有一个ObservableObject,用于在从服务器发送新数据时更新我的 UI(一个包含自定义结构数组的类)。
由于某种原因,发送数据时,ContentView 的body 被调用,但数据没有改变。我什至添加了一个print 语句来检查数组包含的数据是否正确。
当我尝试切换到 TabView 上的另一个选项卡,然后切换回主视图时,UI确实会更新。有人知道为什么 UI 会在我切换标签时更新,尽管 body 会在数据更改时被召回以更新 UI?
主视图
struct HomeView: View {
@ObservedObject private var fbData = firebaseData
var body: some View {
TabView {
//Home Tab
NavigationView {
ScrollView(showsIndicators: false) {
ForEach(self.fbData.posts.indices, id: \.self) { postIndex in
PostView(post: self.$fbData.posts[postIndex])
.listRowInsets(EdgeInsets())
.padding(.vertical, 5)
}
}
.navigationBarTitle("MyPhotoApp", displayMode: .inline)
.navigationBarItems(leading:
Button(action: {
print("Camera btn pressed")
}, label: {
Image(systemName: "camera")
.font(.title)
})
, trailing:
Button(action: {
print("Messages btn pressed")
}, label: {
Image(systemName: "paperplane")
.font(.title)
})
)
} . tabItem({
Image(systemName: "house")
.font(.title)
})
Text("Search").tabItem {
Image(systemName: "magnifyingglass")
.font(.title)
}
Text("Upload").tabItem {
Image(systemName: "plus.app")
.font(.title)
}
Text("Activity").tabItem {
Image(systemName: "heart")
.font(.title)
}
Text("Profile").tabItem {
Image(systemName: "person")
.font(.title)
}
}
.accentColor(.black)
.edgesIgnoringSafeArea(.top)
}
}
FirebaseData:
class FirebaseData : ObservableObject {
@Published var posts = [Post]()
let postsCollection = Firestore.firestore().collection("Posts")
init() {
self.fetchPosts()
}
//MARK: Fetch Data
private func fetchPosts() {
self.postsCollection.addSnapshotListener { (documentSnapshot, err) in
if err != nil {
print("Error fetching posts: \(err!.localizedDescription)")
return
} else {
documentSnapshot!.documentChanges.forEach { diff in
if diff.type == .added {
let post = self.createPostFromDocument(document: diff.document)
self.posts.append(post)
} else if diff.type == .modified {
self.posts = self.posts.map { (post) -> Post in
if post.id == diff.document.documentID {
return self.createPostFromDocument(document: diff.document)
} else {
return post
}
}
} else if diff.type == .removed {
for index in self.posts.indices {
if self.posts[index].id == diff.document.documentID {
self.posts.remove(at: index)
}
}
}
}
}
}
}
【问题讨论】:
-
你能发布更多关于 ObservableObject 如何链接到 ContentView 的代码吗?
-
检查 stackoverflow.com/questions/60727556/… 并尝试了解 SwiftUI 如何知道要“刷新”、“重新加载”...等内容。您的数据和视图之间的关系是通过 '@State' 或 '@ ObservedObject 的属性包装器。 View 观察 State 或 ObservedObject 的内部,如果看到一些变化,它会重新评估其主体。仅此而已,背后没有奇迹。带有大量 .padding、.font .... 等的代码根本没有帮助。
-
@denis_lor 谢谢。我已经用更多信息更新了我的问题。
-
@user3441734 谢谢。我知道属性包装器是如何工作的,
body甚至可以正确回忆,但由于某种原因,只是 UI 本身没有改变。我已经添加了更多信息,如果你能看一下,我会很高兴 -
请发布您的 ObservableObject,这可能是问题的关键部分。
标签: ios swift iphone swiftui combine