SwiftUI - 从 Swift 类启动的可观察对象不会更新 ContentView() 上的 @ObservedObject
Posted
技术标签:
【中文标题】SwiftUI - 从 Swift 类启动的可观察对象不会更新 ContentView() 上的 @ObservedObject【英文标题】:SwiftUI - Observable Object initiated from Swift class does not update @ObservedObject on ContentView() 【发布时间】:2020-07-29 11:53:01 【问题描述】:ObservableObject 类是从 ContentView() 和另一个 Swift 类实例化的。 ObservableObject类的函数在Swift类运行时,不会更新ContentView()的@ObservedObject。
我知道这是因为我两次实例化了 ObservableObject 类。当 Observable 类没有/不能被 ContentView() 实例化时,使用 @ObservedObject 的最佳做法是什么。
我还没有找到让@EnvironmentObject 与 Swift 类一起使用的方法。 我可以使用全局变量并运行 Timer() 来检查对它的更改。然而,这感觉像是一种丑陋的做法?!?
请参阅下面的示例代码。请在设备上运行,查看打印语句。
import SwiftUI
struct ContentView: View
@ObservedObject var observedClass: ObservedClass = ObservedClass()
// The callingObservedClass does not exist on the ContentView, but is called
// somewhere in the app with no reference to the ContentView.
// It is included here to better showcase the issue.
let callingObservedClass: CallingObservedClass = CallingObservedClass()
var body: some View
VStack
// This Text shall be updated, when
// self.callingObservedClass.increaseObservedClassCount() has been executed.
Text(String(observedClass.count))
Button(action:
// This updates the count-variable, but as callingObservedClass creates
// a new instance of ObservedClass, the Text(observedClass.count) is not updated.
self.callingObservedClass.increaseObservedClassCount()
, label:
Text("Increase")
)
class CallingObservedClass
let observedClass = ObservedClass()
func increaseObservedClassCount()
// Returning an Int here to better showcase that count is increased.
// But not in the ObservedClass instance of the ContentView, as the
// Text(observedClass.count) remains at 0.
let printCount = observedClass.increaseCount()
print(printCount)
class ObservedClass: ObservableObject
@Published var count: Int = 0
func increaseCount() -> Int
count = count + 1
return count
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
编辑:我想我的问题是当我无法从 SwiftUI 视图实例化 Swift 类时,如何从 Swift 类获取数据并更新 SwiftUI 视图。
【问题讨论】:
【参考方案1】:一个可能的解决方案是链接 ObservableObject 类。不幸的是,从 ios 13.6 开始,这不能开箱即用。
我通过以下方式找到了答案: How to tell SwiftUI views to bind to nested ObservableObjects
调整和运行示例:
// Add Combine
import Combine
import SwiftUI
struct ContentView: View
@ObservedObject var callingObservedClass: CallingObservedClass = CallingObservedClass()
var body: some View
VStack
// Calling the chained ObservableObject
Text(String(callingObservedClass.observedClass.count))
Button(action:
self.callingObservedClass.increaseObservedClassCount()
, label:
Text("Increase")
)
class CallingObservedClass: ObservableObject
// Chaining Observable Objects
@Published var observedClass = ObservedClass()
// ObservableObject-chaining does not work out of the box.
// The anyCancellable variable with the below init() will do the trick.
// Thanks to https://***.com/questions/58406287/how-to-tell-swiftui-views-to-bind-to-nested-observableobjects
var anyCancellable: AnyCancellable? = nil
init()
anyCancellable = observedClass.objectWillChange.sink (_) in
self.objectWillChange.send()
func increaseObservedClassCount()
let printCount = observedClass.increaseCount()
print(printCount)
class ObservedClass: ObservableObject
@Published var count: Int = 0
func increaseCount() -> Int
count = count + 1
return count
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
如果 ObservableObject-Chaining 不是一个选项,我对如何访问 Swift 类数据和更新 SwiftUI 视图很感兴趣。
如果您对此有解决方案,请在下面回答。
【讨论】:
以上是关于SwiftUI - 从 Swift 类启动的可观察对象不会更新 ContentView() 上的 @ObservedObject的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI-> 线程 1:致命错误:未找到 MyObject.Type 类型的可观察对象(工作表中的 EnvironmentObject)
将数据从委托 Swift 类传递到 SwiftUI 结构中的 EnvironmentObject
Xcode 11 中 Swift Combine.framework 的可选链接