我在没搞懂闭包之前。。项目里的时间处理基本全是代理---因为我把view和controller完全分开了,而且view上的属性我也设置成了私有属性
比如这里
private lazy var btn = UIButton()
在加载自定义cell的时候,我是在cell里写了个方法,然后需要的时候在外面调用
extension CustomeTableViewCell {
/**
加载自定义cell
- parameter at: 所在tableview
- parameter isChange: 是否改变
- parameter CompletionHandle: btn点击事件
- returns: CustomeTableViewCell
*/
class func loadCustomeCell(at: UITableView, change isChange: Bool, handle CompletionHandle: ClickCloseSure) -> CustomeTableViewCell {
var cell = at.dequeueReusableCellWithIdentifier(identifier) as? CustomeTableViewCell
if cell == nil {
cell = CustomeTableViewCell(style: .Default, reuseIdentifier: identifier)
}
cell?.showCellInfo(isChange, handle: CompletionHandle)
return cell!
}
}
我的数据源是这样的
private var dataSource = Array(count: 100, repeatedValue: false)
外面使用方法~~~这里其实可以写在viewModel里面,减少controller的代码。。
其实我对的MVVM中的controller的作用就是通知作用。。。就是通知---view上的所有事件,在controller里调用viewModel里对应事件的方法,调用,调用,调用。。。重要事说三遍。也就是说事件的处理不要放在controller里,controller只是用户点击控件的时候,去调用viewModel里或者其他地方的对应的方法
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = CustomeTableViewCell.loadCustomeCell(tableView, change: dataSource[indexPath.row]) { [unowned self] (call) in
//MARK: cell上btn的点击事件
guard let path = tableView.indexPathForCell(call) else {
return
}
//MARK: 在这里一定要处理好数据源的改变。。。
//MARK: 实际上出现cell重用问题,不是我们自定义cell出现问题,也不是我们加载cell出现问题,而是我们的数据源出现了问题。。数据源出现了问题。。数据源出现了问题,所有重用现象都是因为我们没有及时的对数据源进行处理。
self.dataSource[path.row] = !self.dataSource[path.row]
tableView.reloadRowsAtIndexPaths([path], withRowAnimation: .Fade)
}
return cell
}
这里重申一下!!!!!
在这里一定要处理好数据源的改变。。。
实际上出现cell重用问题,不是我们自定义cell出现问题,也不是我们加载cell出现问题,而是我们的数据源出现了问题。。数据源出现了问题。。数据源出现了问题,所有重用现象都是因为我们没有及时的对数据源进行处理。
处理cell上的事件时,一定要改变数据源对应位置的数据,一定,一定,一定~~~不然可能会出现cell重用现象
当然,首先要定义一个闭包属性
typealias ClickCloseSure = (CustomeTableViewCell) -> ()
private var tap: ClickCloseSure?
这里,显示cell的信息,我设置成立私有方法,外界调用不到。。。
设置私有属性以及私有方法可以保持干净,以及安全性
private extension CustomeTableViewCell {
/**
展示cell信息
在这里为闭包属性赋值
- parameter change: 是否改变
- parameter CompletionHandle: 点击事件
*/
func showCellInfo(change: Bool, handle CompletionHandle: ClickCloseSure) {
contentView.backgroundColor = change ? UIColor.purpleColor() : UIColor.whiteColor()
tap = CompletionHandle
}
}
这里是我自定义cell的部分----我比较喜欢用纯代码布局
private extension CustomeTableViewCell {
func setUpUI() {
btn.frame = CGRectMake(50, 10, contentView.frame.size.width - 100, contentView.frame.size.height - 20)
btn.setTitle("点我改变颜色", forState: .Normal)
btn.backgroundColor = UIColor.cyanColor()
btn.addTarget(self, action: #selector(CustomeTableViewCell.clickBtn), forControlEvents: .TouchUpInside)
contentView.addSubview(btn)
}
/**
uibutton点击事件
*/
@objc func clickBtn() {
//MARK: 先要判断存在,否则会奔溃的
if let clickTap = tap {
clickTap(self)
}
}
}