SimpleTwoWayBinding for iOS
需求
MVVM?为什么不遵循 Apple 推荐的 MVC?Android 的 MVP 并不出色吗?那么酷炫的 VIPER 模式呢?我相信已经有人做出了巨大的努力来解释每种模式为编写的贡献,所以这里的目的不是加入辩论,而只是在已经形成的观点上构建:MVVM 是正确的方式。
作为一个关于 MVVM 是什么的快速入门,它是一个设计模式,其中 ViewModel 在提供数据的数据提供者 Model 和显示提供数据的 View 之间进行调解,如下所示:
在 iOS 中,View 实质上是 ViewController,而 ViewModel 是一个提供为 View 渲染提供精确数据的对象(一个结构)。
这提供了一个松散耦合的架构,可维护(非常薄的观点控制器)并且可测试(ViewModel 抽象出 UI,因此很容易进行测试)。
但仍有隐患:经典的 MVVM 允许模型(作为域模型)实现单一责任原则(并且很美丽),但是,对于贫血模型(当你有很好的 REST APIs 时通常是这样的情况),还需要另一个调解器或表示者,以便促进数据和导航流。
现在,ViewModel 负责更新 View 以及获取有关用户所做的更改的 View 更新。这可以通过使用双向数据绑定以尽可能少的代码来实现。但是... iOS 没有内置双向绑定机制!
幸运的是,我们有了像 RxSwift、RxCocoa 这样的响应式库,但考虑到双向绑定只是响应式编程范式的非常小的一部分,它们过于复杂。 SimpleTwoWayBinding 致力于以一种简单的方式提供双向绑定!
示例
要运行示例项目,请克隆存储库,然后从 Example 目录运行 pod install
。
创建 ViewModel
import SimpleTwoWayBinding
struct FormViewModel {
let name: Observable<String> = Observable()
let companyName: Observable<String> = Observable()
let yearsOfExperience: Observable<Double> = Observable()
let isCurrentEmployer: Observable<Bool> = Observable(false)
let approxSalary: Observable<Float> = Observable()
let comments: Observable<String> = Observable()
}
您希望与视图“绑定”的属性应声明为 Observable。
绑定到 ViewController
class ViewController: UIViewController {
@IBOutlet weak var nameField: UITextField!
@IBOutlet weak var companyField: UITextField!
@IBOutlet weak var isCurrentEmployerSwitch: UISwitch!
@IBOutlet weak var yearsOfExperienceStepper: UIStepper!
@IBOutlet weak var salaryRangeSlider: UISlider!
@IBOutlet weak var selectedSalaryRangeLabel: UILabel!
@IBOutlet weak var selectedYearsOfExperienceLabel: UILabel!
var viewModel: FormViewModel!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.title = "Survey Form"
setupBindings()
}
func setupBindings() {
nameField.bind(with: viewModel.name)
companyField.bind(with: viewModel.companyName)
isCurrentEmployerSwitch.bind(with: viewModel.isCurrentEmployer)
yearsOfExperienceStepper.bind(with: viewModel.yearsOfExperience)
salaryRangeSlider.bind(with: viewModel.approxSalary)
selectedSalaryRangeLabel.observe(for: viewModel.approxSalary) {
[unowned self](_) in
self.selectedSalaryRangeLabel.text =
self.viewModel.getSalaryString()
}
selectedYearsOfExperienceLabel.observe(for: viewModel.yearsOfExperience) {
[unowned self](_) in
self.selectedYearsOfExperienceLabel.text =
self.viewModel.getExperienceString()
}
}
}
UIControl 上的 bind
方法协调了与 Observable 的双向绑定。这就是让表单工作所需的所有代码。请参阅下方的屏幕截图。
安装
SimpleTwoWayBinding 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中
pod 'SimpleTwoWayBinding'
作者
Manish Katoch,[email protected]
许可
SimpleTwoWayBinding 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。