当按照当前的 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/