本文从我们经常遇到的简单实例入手,为您展示最简单的面向协议编程入门:
首先我们是不是经常遇到下面的代码:
注册cell
tableview.register(UINib(nibName: "XXCell", bundle: Bundle.main), forCellReuseIdentifier: "XXCellIdentifier")
从可复用队列里提取cell
tableView.dequeueReusableCell(withIdentifier: "XXCellIdentifier", for: indexPath)
我有个习惯,就是我一般会用cell的名字来命名nibName和Identifier(不知道这样做是否规范)。上述代码是基本在使用tableView的时候就会用到。于是,我们就会想是否有一个一劳永逸的方法解决这个问题。而这就是protocol和extension结合的面向协议的方法:
//用cell的名字生成Identifier和NibName
import UIKit
protocol ReusableView:class {}
extension ReusableView where Self:UIView{
static var reuseIdentifier:String{
return String(describing: self)
}
}
extension UITableViewCell:ReusableView{}
protocol NibLoadableView:class {}
extension NibLoadableView where Self:UIView{
static var NibName:String{
return String(describing: self)
}
}
extension UITableViewCell:NibLoadableView{}
然后我们写一个TableView的模版,简化注册cell和从复用列表查询cell的操作:
import Foundation
import UIKit
extension UITableView{
func fcfRegister<T:UITableViewCell>(_:T.Type) where T:ReusableView, T:NibLoadableView{
let Nib = UINib.init(nibName: T.NibName, bundle: nil)
register(Nib, forCellReuseIdentifier: T.reuseIdentifier)
}
func fcfDequeueReusableCell<T:UITableViewCell>(forIndexPath indexPath:IndexPath)->T where T:ReusableView{
guard let cell = dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as? T else {
fatalError("Could not dequeue cell withidentifier : \(T.reuseIdentifier)")
}
return cell
}
}
OK,这样我们就可以开始使用了:
tableView.delegate = self
tableView.dataSource = self
tableView.fcfRegister(TestCell.self)
extension TestViewController:UITableViewDelegate,UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataArr.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.fcfDequeueReusableCell(forIndexPath: indexPath) as TestCell
return cell
}
}
这就是简单的面向协议编程了,不知道您有木有感觉呢?