程序员落魄的iOS开发

个人对 Swift 中 MVVM 的理解

2020-05-28  本文已影响0人  麻辣柠檬
讲解一下 iOS 中的 MVC 与 MVVM 的一些相似的地方,有些枯燥但是方便理解。
直接进入主题请看后边的代码演示。
搬运一些 MVVM 的基本知识

\color{green}{M}     指的是 Model(就是 MVC 中的 M)
\color{green}{V}       指的是 View (可以理解为 MVC 中的 V + C )
\color{green}{VM}  指的是 ViewModel

这里重点要解释一下\color{green}{VM}
VM 的作用是用来绑定 View 并进行事件转发

其实我们在使用 MVC 的时候就用到了类似 MVVM 的设计模式。
Σ(⊙▽⊙"a 是不是没想到,我之前也没想到。

\color{orange}{不卖关子了}

在iOS中我们都用过 UITableView,
在使用 UITableView 时我们会在 【CellForRow】 方法中将 【CellModel】 传入到自定义的 Cell 中,
而自定义的 Cell 就类似于【ViewModel】,

我们在自定义的 Cell 中创建并添加 View 到 Cell 上,
然后我们通过【CellModel】传进来的数据对 View 进行赋值与逻辑计算。
而【ViewModel】充当的就是类似的角色。

ViewModel 的基本逻辑

1.我们将 【控制器】中初始化的 View 传入到【ViewModel】,这就实现了\color{green}{绑定}
   类似于 Cell 中添加子 View。
2.但是我们并不能直接通过【ViewModel】来操作 View ,
   我们需要在【ViewModel】提供接口来进行对 View 的操作。
3.我们在【控制器】调用【ViewModel】提供的接口对 View 进行操作,这就实现了\color{green}{事件转发}

听起来好像挺简单的,我们实际操作一下
\color{green}{代码演示!!!!!!!!!!!!!!!!!!!!!!!!}

第一步:我们在控制器中创建一个 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的一套简单实现

上一篇 下一篇

猜你喜欢

热点阅读