我们来分析一下...
我的数据模型属性在我的表视图控制器中声明,并且 SwiftUI 视图以模态方式呈现。
这就是你现在所拥有的(可能是简化的)
struct DataModel {
var value: String
}
class ViewController: UIViewController {
var dataModel: DataModel
// ... some other code
func showForm() {
let formView = FormView()
let controller = UIHostingController(rootView: formView)
self.present(controller, animating: true)
}
}
Run Code Online (Sandbox Code Playgroud)
我想要提供的表单输入来操作数据模型。
这里是上面的更新,其中包含将值类型数据传递到 SwiftUI 视图并返回更新/修改/处理的简单演示,无需对 UIKit 部分进行任何必要的重构。
这个想法很简单 - 您按值将当前模型传递到 SwiftUI 中,并在更新的完成回调中将其返回并应用于本地属性(因此,如果设置了任何观察者,它们都会按预期工作)
使用 Xcode 12 / iOS 14 进行测试。
class ViewController: UIViewController {
var dataModel: DataModel
// ... some other code
func showForm() {
let formView = FormView(data: self.dataModel) { [weak self] newData in
self?.dismiss(animated: true) {
self?.dataModel = newData
}
}
let controller = UIHostingController(rootView: formView)
self.present(controller, animated: true)
}
}
struct FormView: View {
@State private var data: DataModel
private var completion: (DataModel) -> Void
init(data: DataModel, completion: @escaping (DataModel) -> Void) {
self._data = State(initialValue: data)
self.completion = completion
}
var body: some View {
Form {
TextField("", text: $data.value)
Button("Done") {
completion(data)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在组织 UI 代码时,最佳实践要求包含 3 个部分:
在 UIKit 中,我们使用MVP方法,其中 UIViewController 子类通常代表秘密酱料部分。
在 SwiftUI 中,由于提供了数据绑定工具,使用MVVM方法更容易。在 MVVM 中,“ViewModel”是秘诀。它是一个自定义结构,用于保存可供您的视图呈现的模型数据,在更新模型数据时触发视图更新,并转发 UI 操作以对您的模型执行某些操作。
例如,编辑名称的表单可能如下所示:
struct MyForm: View {
let viewModel: MyFormViewModel
var body: some View {
Form {
TextField("Name", text: $viewModel.name)
Button("Submit", action: { self.viewModel.submit() })
}
}
}
class MyFormViewModel {
var name: String // implement a custom setter if needed
init(name: String) { this.name = name }
func submit() {
print("submitting: \(name)")
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个,很容易将 UI 操作转发到 UIKit 控制器。一种标准方法是使用委托协议:
protocol MyFormViewModelDelegate: class {
func didSubmit(viewModel: MyFormViewModel)
}
class MyFormViewModel {
weak var delegate: MyFormViewModelDelegate?
func submit() {
self.delegate?.didSubmit(viewModel: self)
}
...
Run Code Online (Sandbox Code Playgroud)
最后,你的 UIViewController 可以实现 MyFormViewModelDelegate,创建一个 MyFormViewModel 实例,并通过设置self为delegate),然后将 MyFormViewModel 对象传递给 MyForm 视图。
改进和其他提示:
didSubmit事件。$viewModel.name语法是一种创建Binding<String>引用nameMyFormViewModel的可变属性的实例的魔法。| 归档时间: |
|
| 查看次数: |
1658 次 |
| 最近记录: |