我希望有一个工作任务可以更新SwiftUI视图。
工作任务正在忙于应用程序的过程性工作 - 播放声音和触发基于计时器的事件。在这些计时器事件期间,我想在SwiftUI视图中闪烁几个图标。因此,我希望触发视图刷新来更新这些图标视图。
因此,我创建了一个名为Settings的environmentObject。它在App Delegate中被实例化,并附加到SceneDelegate中的根视图上。
Settings对象在SwiftUI View层次结构内运行良好。
问题是可怕的:
它与工作类一起在AppDelegate中实例化:
在通过定时器调用的方法内部,我尝试更新环境对象中的一个变量。
工作任务正在忙于应用程序的过程性工作 - 播放声音和触发基于计时器的事件。在这些计时器事件期间,我想在SwiftUI视图中闪烁几个图标。因此,我希望触发视图刷新来更新这些图标视图。
因此,我创建了一个名为Settings的environmentObject。它在App Delegate中被实例化,并附加到SceneDelegate中的根视图上。
Settings对象在SwiftUI View层次结构内运行良好。
问题是可怕的:
Fatal error: No ObservableObject of type Settings found. A View.environmentObject(_:) for Settings may be missing as an ancestor of this view.
我认为问题在于工作类是在AppDelegate中实例化的,而在实例化Settings时它还不是一个ObservableObject。但我很困惑。
环境对象很直观:
import SwiftUI
import Combine
final class Settings: ObservableObject {
@Published var showMenu: Bool = true
@Published var lessonNum: Int = 0
@Published var arrowsOn: Bool = false {
willSet {
willChange.send(self)
}
}
}
let willChange = PassthroughSubject<Settings, Never>()
它与工作类一起在AppDelegate中实例化:
let settings = Settings()
...
var workerClass = WorkerClass()
var leftArrow = LeftArrowView()
然后它被传递给了SceneDelegate:
window.rootViewController = UIHostingController(rootView: contentView
.environmentObject(settings)
使用设置的子视图查看环境对象,以在打开或关闭状态下绘制图标:
import SwiftUI
struct LeftArrowView: View {
@EnvironmentObject var settings: Settings
let leftArrowOnImage = Image("Arrow Left On").renderingMode(.original)
let leftArrowOffImage = Image("Arrow Left Off").renderingMode(.original)
var body: some View {
ZStack {
if settings.arrowsOn {
leftArrowOnImage
} else {
leftArrowOffImage
}
}
}
}
这个工作类是由SwiftUI视图层次结构中更高级别的按钮动作调用的。
在工作类内部,我尝试连接到设置环境对象:
import Combine
public class WorkerClass : NSObject, ObservableObject {
@EnvironmentObject var settings: Settings
在通过定时器调用的方法内部,我尝试更新环境对象中的一个变量。
settings.arrowsOn = !settings.arrowsOn
print("Arrows are \(settings.arrowsOn)")
...这时,我才发现自己未能正确地连接到环境对象。
我错过了什么?
提前感谢任何见解...