突然感觉自己的ViewController太重了,潇潇洒洒1000多行代码,只是为了能快速的把功能堆出来,还未来得及去考虑,如何组织ViewController更合理,让代码的可读性更高。今天抽时间,做了一些优化,因为TableView占了大部分的代码,让ViewController开始臃肿起来。
对于如何打造轻ViewController和分离TableView,objc中国分享的文章相当不错,可见平时大家阅读的质量要保持。
- 更轻量的 View Controllers
- 整洁的 Table View 代码
这里我将使用Swift1.2编写一个示例代码(Demo)来讲述如何分离TableView,objc中国给出的例子是Objective-C版本,所以就不重复造轮子了。
大家可以访问 separation UITableView 来获取示例(Demo)。
分离的思路要点
- 继承UITableView编写一个基类,主要提供两个注册方法,其一为注册Cell,其二为注册datasource和delegate
- 继承UITableViewCell编写一个基类(可选),如果存在基类,可以提供一些静态方法,比如返回当前Class String之类的
- 继承NSObject编写一个基类,并实现UITableViewDataSource和UITableViewDelegate协议,主要实现tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int和tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell方法,也可以提供一个自己的协议去实现Event Handler处理,来方便开发者编写业务代码
- 将模型处理与datasource分离,objc中国实现的思路是设置一个category来处理,我是在自己写的Cell类中提供一个setter 方法。
实现
说白了,分离UITableView最关键的地方,是去抽离datasource与delegate,所以继承与NSObject自写的基类是非常重要的,对于一个简单的示例,我只写了一个loadMoreData的方法,来添加数据,也许你还可以写的更多。
import UIKit @objc protocol eventHandler{ optional func handler(indexPath:NSIndexPath,didSelectRowAtObj anyObj:AnyObject)->Void } class SEPTableViewExtend: NSObject,UITableViewDataSource,UITableViewDelegate{ var dataArray:NSMutableArray? var SEPDelegate:eventHandler? override init() { self.dataArray = NSMutableArray() } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.dataArray!.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell:SEPTableViewCell = tableView.dequeueReusableCellWithIdentifier(NSStringFromClass(SEPTableViewCell.classForCoder()), forIndexPath: indexPath) as! SEPTableViewCell cell.SEPString = self.dataArray?.objectAtIndex(indexPath.row) as! String return cell } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { self.SEPDelegate?.handler!(indexPath, didSelectRowAtObj: self.dataArray!.objectAtIndex(indexPath.row)) } func loadMoreData(obj:AnyObject){ self.dataArray?.addObject(obj) } }
这时候,我们需要将model数据传入到view中去赋值,同时我们也希望model与view,datasource可以分离的比较清楚,让datasource的方法变的简单,只需要一句设置即可。
private var _SEPString:String? var SEPString:String!{ get{ return self._SEPString! } set(newValue){ self._SEPString = newValue self.textLabel?.text = newValue } }
对于Event的处理,统一提供一个代理,比如eventHandler(当然这名字是我随便取的),代理中可以对数据进行一些处理,不需要直接返回Apple的原始数据,应该让开发者易用。
@objc protocol eventHandler{ optional func handler(indexPath:NSIndexPath,didSelectRowAtObj anyObj:AnyObject)->Void } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { self.SEPDelegate?.handler!(indexPath, didSelectRowAtObj: self.dataArray!.objectAtIndex(indexPath.row)) }
当然,这是一个简单的示例,比如控制多个Cell的转发,TableView编辑特性等等都未实现,但这是一个开始,希望大家共同努力;
谢谢你抽出宝贵时间,阅读完此篇博文。