protocols - 如何使用@Published 属性包装器定义协议(protocol)以包含属性

标签 protocols swiftui combine

当按照当前的 SwiftUI 语法使用@Published 属性包装器时,似乎很难定义一个包含@Published 属性的协议(protocol),或者我肯定需要帮助:)

当我在 View 和它的 ViewModel 之间实现依赖注入(inject)时,我需要定义一个 ViewModelProtocol 以便注入(inject)模拟数据以轻松预览。

这是我第一次尝试,

protocol PersonViewModelProtocol {
    @Published var person: Person
}

我得到“在协议(protocol)中声明的属性‘人’不能有包装器”。

然后我尝试了这个,
protocol PersonViewModelProtocol {
    var $person: Published
}

显然没有用,因为 '$' 是保留的。

我希望有一种方法可以在 View 和它的 ViewModel 之间放置一个协议(protocol),并利用优雅的 @Published 语法。非常感谢。

最佳答案

我的 MVVM 方法:

// MARK: View

struct ContentView<ViewModel: ContentViewModel>: View {
    @ObservedObject var viewModel: ViewModel

    var body: some View {
        VStack {
            Text(viewModel.name)
            TextField("", text: $viewModel.name)
                .border(Color.black)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(viewModel: ContentViewModelMock())
    }
}

// MARK: View model

protocol ContentViewModel: ObservableObject {
    var name: String { get set }
}

final class ContentViewModelImpl: ContentViewModel {
    @Published var name = ""
}

final class ContentViewModelMock: ContentViewModel {
    var name: String = "Test"
}
这个怎么运作:
  • ViewModel协议(protocol)继承 ObservableObject , 所以 View将订阅ViewModel变化
  • 房产 name有getter和setter,所以我们可以把它当作Binding
  • View变化name属性(通过 TextField)然后通过 @Published 通知 View位于 ViewModel 的属性(property)(并且 UI 已更新)
  • 创建 View根据您的需要使用实际实现或模拟

  • 可能的缺点:View必须是通用的。

    关于protocols - 如何使用@Published 属性包装器定义协议(protocol)以包含属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57517320/

    相关文章:

    ios - 使用SwiftUI的UINavigationBar的自定义背景色

    swiftui - 在 SwiftUI 中使用 aspectRatio 的方形文本

    ios - 如何告诉 SwiftUI View 绑定(bind)到多个嵌套的 ObservableObject

    ios - 协议(protocol)的 NSMethodSignature

    protocols - 最有效的双氢睾酮

    swift - 如何为 UIPageViewControllerDataSource 提供默认实现?

    string - 使文本编辑器动态高度 SwiftUI

    swift - 单击按钮后计时器发布者初始化计时器

    swift - 如何限制 Combine 中的 flatMap 并发性仍然处理所有源事件?

    iOS:协议(protocol)如何确保类匿名?