个人对 Swift 中 MVVM 的理解
讲解一下 iOS 中的 MVC 与 MVVM 的一些相似的地方,有些枯燥但是方便理解。
直接进入主题请看后边的代码演示。
搬运一些 MVVM 的基本知识
指的是 Model(就是 MVC 中的 M)
指的是 View (可以理解为 MVC 中的 V + C )
指的是 ViewModel
这里重点要解释一下
![]()
VM 的作用是用来绑定 View 并进行事件转发
其实我们在使用 MVC 的时候就用到了类似 MVVM 的设计模式。
Σ(⊙▽⊙"a 是不是没想到,我之前也没想到。
在iOS中我们都用过 UITableView,
在使用 UITableView 时我们会在 【CellForRow】 方法中将 【CellModel】 传入到自定义的 Cell 中,
而自定义的 Cell 就类似于【ViewModel】,我们在自定义的 Cell 中创建并添加 View 到 Cell 上,
然后我们通过【CellModel】传进来的数据对 View 进行赋值与逻辑计算。
而【ViewModel】充当的就是类似的角色。ViewModel 的基本逻辑
1.我们将 【控制器】中初始化的 View 传入到【ViewModel】,这就实现了
。
类似于 Cell 中添加子 View。
2.但是我们并不能直接通过【ViewModel】来操作 View ,
我们需要在【ViewModel】提供接口来进行对 View 的操作。
3.我们在【控制器】调用【ViewModel】提供的接口对 View 进行操作,这就实现了
听起来好像挺简单的,我们实际操作一下
第一步:我们在控制器中创建一个 UILabel ,一个 UIButton
import UIKit class MVVMController: UIViewController { private let textLabel = UILabel() private let textBtn = UIButton() override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .white } }
第二步:我们创建一个虚拟 Model 来进行演示
import UIKit class MVVMTextModel: NSObject { let labelVlaue = "我是一个Label" let btnValue = "我是一个Btn" }
第三步:我们创建一个【ViewModel】并设置需要绑定的 View 与 初始值
import UIKit class MVVMTextViewModel: NSObject { private var textLabel: UILabel private var textBtn: UIButton init(label: UILabel, btn: UIButton) { textLabel = label textBtn = btn textLabel.text = "Label" textBtn.setTitle("Btn", for: .normal) textBtn.setTitleColor(.black, for: .normal) } } 注意:我们将 View 设置为私有是为了防止控制器直接调用 View 修改数据 注意:我们初始化时设置了一些基本的属性 【根据实际情况也可以在其他地方设置默认属性】
第四步:我们在控制器中创建 Model 与 ViewModel 并将 View 绑定到 ViewModel 中
【在这里我习惯使用 extension 分隔各代码块的功能,使代码布局更清晰一些】import UIKit class MVVMController: UIViewController { private let textLabel = UILabel() private let textBtn = UIButton() let model = MVVMTextModel() var viewModel: MVVMTextViewModel! override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .white createUI() createViewModel() } } //MARK: UI extension MVVMController { func createUI() { self.view.addSubview(textLabel) self.view.addSubview(textBtn) textLabel.frame = CGRect(x: 100, y: 100, width: 200, height: 50) textBtn.frame = CGRect(x: 100, y: 200, width: 200, height: 50) } } //MARK: ViewModel extension MVVMController { func createViewModel() { viewModel = MVVMTextViewModel(label: textLabel, btn: textBtn) } }
现在我们就已经完成了 View 的基本绑定,接下来我们实现事件的传递
说白了就是在 【ViewModel】 中实现一些接口,在需要时直接调用
我们在 【ViewModel】实现修改文字的接口 与 点击 Btn 更换随机背景色的接口
import UIKit class MVVMTextViewModel: NSObject { private var textLabel: UILabel private var textBtn: UIButton var labelValue: String? { set {textLabel.text = newValue} get {return textLabel.text} } var btnValue: String? { set {textBtn.setTitle(newValue, for: .normal)} get {return textBtn.title(for: .normal)} } init(label: UILabel, btn: UIButton) { textLabel = label textBtn = btn textLabel.text = "Label" textBtn.setTitle("Btn", for: .normal) textBtn.setTitleColor(.black, for: .normal) } /// 设置btn随机色 func setTextBtnRandom() { textBtn.backgroundColor = UIColor.random() // 自己写的方法 } }
然后我们在控制器中添加【点击事件】并【调用接口】
import UIKit class MVVMController: UIViewController { private let textLabel = UILabel() private let textBtn = UIButton() let model = MVVMTextModel() var viewModel: MVVMTextViewModel! override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .white createUI() createViewModel() createAction() } } //MARK: UI extension MVVMController { func createUI() { self.view.addSubview(textLabel) self.view.addSubview(textBtn) textLabel.frame = CGRect(x: 100, y: 100, width: 200, height: 50) textBtn.frame = CGRect(x: 100, y: 200, width: 200, height: 50) } } //MARK: ViewModel extension MVVMController { func createViewModel() { viewModel = MVVMTextViewModel(label: textLabel, btn: textBtn) } } //MARK: Action extension MVVMController { func createAction() { textBtn.addTarget(self, action: #selector(clickTextBtn), for: .touchUpInside) } /// 点击修改背景颜色 @objc func clickTextBtn() { viewModel.setTextBtnRandom() } /// 点击View修改text内容 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { viewModel.labelValue = model.labelVlaue viewModel.btnValue = model.btnValue } }
文件目录
以上就是完整的代码了,觉得有用的请点个赞,觉得有问题的也希望能指出。
参考内容:基于Swift的MVVM的一套简单实现