swiftui - SwiftUI MVVM 绑定
问题描述
如何将 a 传递给@Binding
ViewModel。
让我们考虑一个简单的例子,
struct TopView: View {
@State var isPresented: Bool
var body: some View {
SubView(isPresented: $isPresented)
}
}
struct SubView: View {
@Binding var isPresented: Bool
}
然后,如果我们想要一个 MVVM 模式,
@Binding
在中使用安全ObservableObject
吗?
例如,写作是否安全,
struct TopView: View {
@State var isPresented: Bool
var body: some View {
SubView(model: SubViewModel(isPresented: $isPresented))
}
}
struct SubView: View {
@ObservedObject var model: SubViewModel
}
// In "SubViewModel.swift"
import Foundation
import Combine
import SwiftUI
public final class SubViewModel: ObservedObject {
@Binding var isPresented: Bool
public init(isPresented: Binding<Bool>) {
self._isPresented = isPresented
}
}
你会怎么做?类似的包括如何将 environmentObject 传递给视图模型?
解决方案
您正在描述ObservableObject
.
@Binding
并且@State
仅用于View
Apple SwiftUI 教程可能对您了解 SwiftUI 概念很有帮助。https://developer.apple.com/tutorials/swiftui/
您的代码中有一些基本错误我在下面的代码中提到了更改。
import SwiftUI
struct PassingBinding: View {
var body: some View {
TopView1()//Best Practice
//TopView2()//Singleton Pattern
}
}
///This is the best way to do it
///https://developer.apple.com/tutorials/swiftui/handling-user-input
struct TopView1: View {
@StateObject var model: SubViewModel = SubViewModel()
var body: some View {
VStack{
SubView1().environmentObject(model)
Button(action: {
self.model.isPresented.toggle()
}, label: {
Text("Toggle isPresented")
})
}
}
}
struct SubView1: View {
@EnvironmentObject var model: SubViewModel
var body: some View {
Text("SubView - isPresented == \(model.isPresented.description)")
}
}
///Another way that has some specifc uses is to use a Singleton model
///https://developer.apple.com/documentation/swift/cocoa_design_patterns/managing_a_shared_resource_using_a_singleton
struct TopView2: View {
@StateObject var model: SubViewModel = SubViewModel.shared
var body: some View {
VStack{
SubView2()
Button(action: {
self.model.isPresented.toggle()
}, label: {
Text("Toggle isPresented")
})
} }
}
struct SubView2: View {
@StateObject var model: SubViewModel = SubViewModel.shared
var body: some View {
Text("SubView - isPresented == \(model.isPresented.description)")
}
}
///This item can be Observed "ObservableObject" vs I am Observing this object "ObservedObject"
///https://developer.apple.com/documentation/combine/observableobject
public final class SubViewModel: ObservableObject {
static let shared: SubViewModel = SubViewModel()//Singleton Pattern
@Published var isPresented: Bool = false //Initialize here this is the source for the View
//@Binding and @State is are only used in View struct not in an ObservableObject.https://developer.apple.com/documentation/swiftui/binding
}
struct PassingBinding_Previews: PreviewProvider {
static var previews: some View {
PassingBinding()
}
}
推荐阅读
- https - Android 应用程序一旦连接到 Fiddler,就会失去互联网连接
- python - 如何使这个乐透计划可重复
- raku - Perl6:如何从命令行读取混合参数?
- python - 使用 holt-winters 模型进行预测
- python-3.x - 如何将每个整数“一一”相乘并“按渐进顺序”显示结果,直到所有整数相乘得出整体乘积
- plugins - Visual Studio 代码扩展变量
- python - AttributeError:“模块”对象没有属性“液晶显示器”
- rest - WooCommerce rest api包括参数不获取可变产品的变化
- scala - 在 Scala 中计算素数流的代码
- java - 在java中重新分配其复制引用时更改原始对象