Swift UI - EnvironmentObject 更改不会更新 UI
Posted
技术标签:
【中文标题】Swift UI - EnvironmentObject 更改不会更新 UI【英文标题】:Swift UI - EnvironmentObject change does not update UI 【发布时间】:2019-11-29 16:43:12 【问题描述】:关于以下问题,我正用头撞桌子。我有一个嵌套的 DataStore(为方便起见),通过 @EnvironmentObject 集成到一个视图中。如果我在 DataStore 中更改某些内容(例如,将新对象放入其中 - 效果很好),UI 不会更新。
在控制台中,我还得到了 print("Object Changed") 的结果,这是由于获取的结果发生了变化。但 UI 仅在我重新启动应用程序后更新。这里有什么问题?
提前非常感谢!
我的测试代码如下所示:
数据存储:
import Foundation
import Combine
class DataStore : ObservableObject
@Published var documents = DocumentStore()
@Published var attachments = AttachmentStore()
附件商店
//
// AttachmentStore.swift
import SwiftUI
import Combine
import CoreData
class AttachmentStore: NSObject, ObservableObject
// MARK: Private Properties
let persistenceManager = PersistenceManager()
private lazy var fetchedResultsController: NSFetchedResultsController<ManagedAttachment> =
let fetchRequest: NSFetchRequest<ManagedAttachment> = ManagedAttachment.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "dateCreated", ascending: false)]
let fetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: self.persistenceManager.managedObjectContext,
sectionNameKeyPath: nil,
cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
()
private var attachment: [ManagedAttachment]
return fetchedResultsController.fetchedObjects ?? []
// MARK: Public Properties
@Published var Items : [ManagedAttachment] = []
public var allItems: [ManagedAttachment]
return self.attachment.filter $0 == $0
func setup()
self.Items = allItems
// MARK: Object Lifecycle
override init()
super.init()
fetchDocuments()
setup()
// MARK: Public Methods
public func allAttachments(for id: UUID) -> [ManagedAttachment]
let attachments = self.allItems.filter $0.parentID == id
return attachments
public func create(attachment: Attachment)
ManagedAttachment.create(object: attachment, in: self.persistenceManager.managedObjectContext)
saveChanges()
public func delete(attachment: ManagedAttachment)
persistenceManager.managedObjectContext.delete(attachment)
self.saveChanges()
public func update()
self.saveChanges()
// MARK: Private Methods
private func fetchDocuments()
do
try fetchedResultsController.performFetch()
dump(fetchedResultsController.sections)
catch
fatalError()
private func saveChanges()
guard persistenceManager.managedObjectContext.hasChanges else return
do
try persistenceManager.managedObjectContext.save()
self.objectWillChange.send()
print("Object Changed")
catch fatalError()
extension AttachmentStore: NSFetchedResultsControllerDelegate
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
self.objectWillChange.send()
print("Object Changed")
TestView
import SwiftUI
struct TestView: View
@EnvironmentObject var data : DataStore
var body: some View
VStack
Button(action:
self.data.attachments.create(attachment: Attachment(url: "Test"))
)
Text("Add")
// Print the Items in the DataStore
ForEach(data.attachments.Items, id:\.self)Item in
Text(Item.url).font(.caption)
【问题讨论】:
看到这个答案:***.com/a/58917498/6570854 究竟是什么不工作?除了setup()
,我没有看到你在任何地方改变Items
@ribilynn: 非常感谢 - 我修好了。我的问题是我从 attachmentStore 发送了 willChange - 但不是从 datastore 对象发送。非常感谢!
【参考方案1】:
好的,我的问题是我从附件存储区发送了一个 willChange,而不是从数据存储区,所以它没有更新。所以解决办法是手动调用dataStore.objectWillChange.send()。谢谢!
【讨论】:
以上是关于Swift UI - EnvironmentObject 更改不会更新 UI的主要内容,如果未能解决你的问题,请参考以下文章