And*_*eda 3 observable ios swiftui combine
我想让一个工作任务更新 SwiftUI 视图。
工作任务正忙于执行应用程序的程序性工作 - 播放声音和触发基于计时器的事件。我想在这些计时器事件期间在 SwiftUI 视图中闪烁几个图标。所以我想在这些图标视图中触发视图刷新。
因此,我创建了一个名为 Settings 的 environmentObject。它在 App Delegate 中实例化,并附加到 SceneDelegate 中的根视图。
Settings 对象在 SwiftUI 视图层次结构中工作得很好。
问题是可怕的:
Fatal error: No ObservableObject of type Settings found. A View.environmentObject(_:) for Settings may be missing as an ancestor of this view.
Run Code Online (Sandbox Code Playgroud)
我认为问题在于工作类是在 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>()
Run Code Online (Sandbox Code Playgroud)
它与工作类一起在 AppDelegate 中实例化:
let settings = Settings()
...
var workerClass = WorkerClass()
var leftArrow = LeftArrowView()
Run Code Online (Sandbox Code Playgroud)
它被传递给 SceneDelegate:
window.rootViewController = UIHostingController(rootView: contentView
.environmentObject(settings)
Run Code Online (Sandbox Code Playgroud)
使用设置的子视图查看环境对象以在打开或关闭状态下绘制图标:
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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
worker 类在 SwiftUI 视图层次结构中被称为 Button 操作。
在 worker 类中,我尝试附加到设置环境对象:
import Combine
public class WorkerClass : NSObject, ObservableObject {
@EnvironmentObject var settings: Settings
Run Code Online (Sandbox Code Playgroud)
在通过计时器调用的方法中,我尝试更新环境对象中的变量:
settings.arrowsOn = !settings.arrowsOn
print("Arrows are \(settings.arrowsOn)")
Run Code Online (Sandbox Code Playgroud)
...这是当我发现我没有真正正确地附加到环境对象时。
我错过了什么?
提前感谢您的任何见解...
该@EnvironmentObject包装是只SwiftUI视图内使用,在其他地方,你可以在常规方式使用引用类型,所以这里是可能的解决方案
public class WorkerClass : NSObject, ObservableObject {
var settings: Settings // reference property
Run Code Online (Sandbox Code Playgroud)
当创建
let settings = Settings()
...
var workerClass = WorkerClass(settings: settings) // << same settings as in view
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2055 次 |
| 最近记录: |