如何从另一个 class 在 SwiftUI 中编辑 ObservableObject 的属性?

How do you edit an ObservableObject’s properties in SwiftUI from another class?

我正在寻找合适的模式和语法来实现我的目标,即拥有一个可以在多个视图之间共享的 ObservableObject 实例,同时保持与它相关的逻辑包含在另一个 class 中。我希望这样做是为了允许不同的“控制器”classes 操纵状态的属性,而视图不需要知道哪个控制器正在作用于它(注入)。

以下是说明问题的简化:

import SwiftUI

class State: ObservableObject {
    @Published var text = "foo"
}

class Controller {
    var state : State
    init(_ state: State) {
        self.state = state
    }
    
    func changeState() {
        state.text = "bar"
    }
}

struct ContentView: View {
    @StateObject var state = State()
    var controller: Controller!
    
    init() {
        controller = Controller(state)
    }
    
    var body: some View {
        VStack {
            Text(controller.state.text) // always shows 'foo'
            Button("Press Me") {
                print(controller.state.text) // prints 'foo'
                controller.changeState()
                print(controller.state.text) // prints 'bar'
            }
        }
    }
}

我知道我可以直接使用我的 ObservableObject 并操纵它的属性,这样 UI 就会更新响应,但在我的情况下,这样做会阻止我根据不同的情况拥有不同的“控制器”实例需要发生。请告知在 SwiftUI

中完成此类场景的最佳方法

要使 SwiftUI 视图跟随状态更新,您的控制器需要 ObservableObject

SwiftUI 视图将在 objectWillChange 被触发时更新 - 对于使用 Published 注释的属性会自动更新,但您也可以手动触发它。

使用与您所在州相同的发布者,您可以同步两个可观察对象,例如:

class Controller: ObservableObject {
    let state: State
    private var cancellable: AnyCancellable?
    init(_ state: State) {
        self.state = state

        cancellable = state.objectWillChange.sink {
            self.objectWillChange.send()
        }
    }

    func changeState() {
        state.text = "bar"
    }
}

struct ContentView: View {
    @StateObject var controller = Controller(State())