UIViewController和UIView
Controller
顾名思义,主要是用来做控制的,View
是用来做UI展示的.但在实际的开发中,往往会将Controller
和View
都作为UI层来展示,这样做会有什么问题?
-
View
将不光负责展示控件,还需要处理业务数据,业务逻辑.对于一个业务逻辑很强的View
这样做还可以,比如用户的头像控件,就是和用户个人资料有很强业务关系的,这种做法是合理的.但如果是一个普通的View
,比如一个底部工具条,里面有很多按钮,显然再用View
处理业务逻辑和数据是不合理的,这样的View
是没法复用的,如果你说:我不复用View
,那就呵呵了. -
Controller
里面可能存在大量的UI控件,各种创建控件的代码,各种代理,回调,数据读取,网络请求,业务数据适配,这样的ViewController
将会变得非常庞大.ViewController
就是一个页面,一个完整的页面,要用ViewController
就是想用些和生命周期有关的ViewController
特有的东西,如果只是通过ViewController
加载一个view
,那最好直接用view
.通常来讲ViewController
是不能够复用的,如果你从StoryBoard
中连了很多控件到ViewController
中,而那个StoryBoard
中要是还有很多约束,那随着业务的发展,这份代码离无法维护的日子就不远了.
那Controller应该做什么:
- 初始化UI(极少了的UI细节,各种自定义UIView)
-
addObserver
设置delegate
,可能还有addTag
,addGesture
(极少的) - 同步取本地数据,异步取网络数据.(UI展示的数据,即使是同步数据也不应该在
Controller
里初始化),对于数据,这里应该是封装了的数据,也就是说,一个View
对应一个Model
,而不应该是零散的数据,拼凑的. - 在代理和
observer
的回调中更新UI,这里的更新UI只要1句话,把数据全都通过View
的public interface
丢给View
,至于View
想用什么,想怎么更新,都是它自己的事情(这里的View
包括自定义的TableViewCell
,CollectionViewCell
,自定义的View
),当然对于部分更新UI还是要在View
中暴露几个public property
. - 如果你使用自动布局或者
Masonry
要手动码一些addConstraints
这样类似的代码,或者你使用frame
,那你要在viewDidLayoutSubviews
设置每个view
的frame
- 最核心的部分,负责页面的跳转,跳转也就是一句话,
[XXXViewController xxx:]
;这里需要在ViewController
里面实现一个或者多个类方法,方便外部调用和传递参数,这里参数还是建议封装成一个model
,只传一个参数,里面具体是什么自己去解析.这里ViewController
只关心跳哪里,具体怎么跳,不需要写在本ViewController
里. - 动态展示一些子
view,alertView,messageBox
, 这里是把ViewController
弄乱的最好的地方,因为动态添加的view
可能是动画,所以尽量把view中动画有关的东西都封装到view
中,ViewController
只通过1-2句代码创建View
并完成动画,而View
给ViewController
传递消息和数据统统都通过代理的方式,最后ViewController
只要在某个代理里remove
这个view
就可以了.
所以整个ViewController
写下来import
的东西应该是类似这样的
#import "XXXViewController.h"
#import "XXXModel.h"
.....
#import "XXXView.h"
....
#import "XXXViewCell.h"
....
至于从model
中获取的数据不是view
要显示的数据应该怎样做数据的适配呢?这里就要使用到ViewModel
,为避免文章过长,下一篇详细说明如何在已有的big VC
中增加VM
来瘦身VC
.