用MVVM设计复杂的cell(光棍必看)
本文根据一个简单的例子来阐述MVVM框架设计模式.
![](https://img.haomeiwen.com/i3275951/a63e1ede139e898c.png)
如图,像这种cell我们可以在微博,新闻等很多软件看到. 这种cell的特点就是比较复杂, 它的高度是不确定的, 是根据网络请求回来的数据动态计算高度的.
cell的高度我们是通过table view的一个代理方法
heightForRowAtIndexPath来设置的,而这个方法是要写在控制器里面的.这就意味着如果我们用MVC的模式,那么就意味着我们要在控制器的这个代理方法里面动态的计算cell 的高度,像这种复杂的cell计算的的代码是非常多的. 这就让我们的控制器里面要写的代码非常多. 这样子控制器将非常臃肿.
而我们是面向模型开发,我们希望控制器里面不要参杂太多的业务逻辑,我们希望控制器只是一个调配资源的角色, 就像总经理一样吩咐着各种女秘书去做事, 而自己不用具体地做事.
那就在这里引入MVVM的概念.我们希望把cell的高度计算都写在另外一个地方(这个地方叫View Model).
首先介绍一下MVVM:
M是指Model: 保存网络数据
V是指View: 展示UI界面
VM是指View Model: 保存View的具体参数,包括内容和frame等
使用MVVM的好处是逻辑性非常强,扩展性非常好, 写代码的人写起来会非常顺畅且有条理性.
MVVM的缺点就是阅读性不好,对于不太熟练的人读起来会比较有难度, 这就一定程度导致维护成本的增加.
那么我们现在有4个东西: Controller, Model, View, View Model
这4个东西相互之间是怎么通讯和信息传递的呢? 请看下图:
![](https://img.haomeiwen.com/i3275951/ccea098136c999e3.png)
在控制器中,拿到网络请求回来的数据, 转化为View Model, 再把View Model赋值给View . View拿到View Model后,根据View Model的参数来展示数据.
那么我们回到头文的例子,我们把这个cell划分为三个小块View, 把这三个View添加并展示在cell上:
![](https://img.haomeiwen.com/i3275951/4431bf0c96336fee.png)
![](https://img.haomeiwen.com/i3275951/c8317e04bf8e9e7c.png)
![](https://img.haomeiwen.com/i3275951/6a68e07ade8238f3.png)
![](https://img.haomeiwen.com/i3275951/4f2d162c554f3f5f.png)
![](https://img.haomeiwen.com/i3275951/4c920cdaae296f89.png)
在控制器中,拿到网络数据,并转成View Model,然后给cell的vm属性赋值
![](https://img.haomeiwen.com/i3275951/fad02972a20fb2ad.png)
![](https://img.haomeiwen.com/i3275951/bf3f6edb5d243c8f.png)
在View Model中重写item属性的setter方法,计算cell的具体高度
![](https://img.haomeiwen.com/i3275951/70152193bf351157.png)
![](https://img.haomeiwen.com/i3275951/f58dddd5aad1ce02.png)
在cell中创建各个子view,并重写view model属性的setter方法,给子view的item属性赋值
![](https://img.haomeiwen.com/i3275951/b4eb709b7a130392.png)
在子View中拿到item,重写item属性的setter方法并把item展示的网络数据展示在UI界面
![](https://img.haomeiwen.com/i3275951/b1267b71dc00dfc0.png)
网络数据传递的过程是:
控制器 --(通过ViewModel)--> cell --(通过item)--> 子View
最后请看下图,我保证你不会再滚到头文中再看一遍第一张图
![](https://img.haomeiwen.com/i3275951/4218538218989f60.png)