iOS MVVM模式
MVVM如图,是为了解决MVC在大项目里VC变得臃肿的模式
典型的MVC就如写个简单的TableView,逻辑都扔到VC里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { let tableView: UITableView = { let tableView = UITableView() tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") return tableView }() let data = ["1", "2", "3"]
override func viewDidLoad() { super.viewDidLoad() view.addSubview(tableView) tableView.delegate = self tableView.dataSource = self } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() tableView.frame = view.bounds } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = data[indexPath.row] return cell } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { data.count } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) } }
|
随着Data的变化,抽取出ViewModel这一概念,使得cell的数据和视图的更新多了一层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| struct User { let name: String let nation: String }
struct CellViewModel { let name: String let nation: String }
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { let tableView: UITableView = { let tableView = UITableView() tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") return tableView }() let data = [ User(name: "haoboxuxu", nation: "China"), User(name: "Batman", nation: "Gotham"), User(name: "Hopper X", nation: "Space"), ]
override func viewDidLoad() { super.viewDidLoad() view.addSubview(tableView) tableView.delegate = self tableView.dataSource = self } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() tableView.frame = view.bounds } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let model = data[indexPath.row] let viewModel = CellViewModel(name: model.name, nation: model.nation) cell.textLabel?.text = "\(viewModel.name) \(viewModel.nation)" return cell } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { data.count } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) } }
|
你可能觉得这样和MVC没什么大区别,但是到了如果要自定义cell或者其他自定义视图的场景就更加展现出用途
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| class CustomCell: UITableViewCell { @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var nationLabel: UILabel! static let cellID = "CustomCell" static func nib() -> UINib { return UINib(nibName: "CustomCell", bundle: nil) }
override func awakeFromNib() { super.awakeFromNib() }
override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) } func configWith(_ vm: CellViewModel) { nameLabel.text = vm.name nationLabel.text = vm.nation } }
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { let tableView: UITableView = { let tableView = UITableView() tableView.register(CustomCell.nib(), forCellReuseIdentifier: CustomCell.cellID) return tableView }()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.cellID, for: indexPath) as! CustomCell let model = data[indexPath.row] let viewModel = CellViewModel(name: model.name, nation: model.nation) cell.configWith(viewModel) return cell } }
|
当当!