首页 > 解决方案 > 为什么嵌套发布者没有在 SwiftUI/Combine 中调用我的自定义发布者?

问题描述

这是如何在 SwiftUI 中的两个视图模型之间共享已发布模型的后续问题?.

为了使嵌套发布的模型真正发布,我使用了这里描述的一种方法:如何告诉 SwiftUI 视图绑定到嵌套的 ObservableObjects。到目前为止一切顺利,手动 objectWillChange 传递工作并且更改由父视图模型发布。

但是,如果我尝试使用自定义发布者,它利用已发布的嵌套模型,它们就不会像我习惯的那样运行(使用常规发布的属性)。这是一个简化的例子。

我错过了什么吗?

import SwiftUI
import Combine

struct ContentView: View {
    @StateObject var contentViewModel = ContentViewModel()
    var body: some View {
        VStack{
            // Both toggle together, indicating that objectWillChange works correctly
            ModelEditView(model: contentViewModel.model)
            ModelEditView(model: contentViewModel.model)
            // This toggle binds another not nested published property
            Toggle("Not Nested Toggle", isOn: $contentViewModel.isToggled)
            // Custom toggleChangedPublisher only works with the not nested property
            Text(contentViewModel.internalChangedValue ? "true" : "false")
        }
    }
}

class Model: ObservableObject {
    @Published var nestedIsToggled = false
}

class ContentViewModel: ObservableObject {
    //Nested Model
    @Published var model = Model()
    //Not nested model equivalent
    @Published var isToggled = false
    //Property only altered by the custom toggleChangedPublishers
    @Published var internalChangedValue = false
    
    var anyCancellables = Set<AnyCancellable>()
    
    init() {
        // This should notify the "parent" ContentViewModel of changes in nested model
        anyCancellables.insert(model.objectWillChange.sink { [weak self] (_) in
            self?.objectWillChange.send()
        })
        nestedToggleChangedPublisher
            .receive(on: RunLoop.main)
            .assign(to: \.internalChangedValue, on: self)
            .store(in: &anyCancellables)
        toggleChangedPublisher
            .receive(on: RunLoop.main)
            .assign(to: \.internalChangedValue, on: self)
            .store(in: &anyCancellables)
        
    }
    private var nestedToggleChangedPublisher: AnyPublisher<Bool, Never> {
        // Not working on change of model
        $model
            .map({return $0.nestedIsToggled})
            .eraseToAnyPublisher()
    }
    

    private var toggleChangedPublisher: AnyPublisher<Bool, Never> {
        // Is working when toggled
        $isToggled
            .eraseToAnyPublisher()
    }
}

谢谢你的支持!

标签: iosswiftswiftuicombinepublisher

解决方案


也许我错过了重点,但你不能只使用计算属性吗?

class ContentViewModel: ObservableObject {
    @Published var model = Model()

    var isToggled: Bool { model.nestedIsToggled }
}

推荐阅读