起因
UITableView
是我们用到最多的数据展示工具之一,它强大的功能给我们提供了很大的便利。
所以现在就抽取一个协议,去控制UITableView的配置。
代码
protocol TableDeploy{
associatedtype dataType
var dataSource:[dataType]{set get}
associatedtype cellType:UITableViewCell
func registerCell(_ table:UITableView, with cellId:String,and cellHeight:CGFloat)
}
extension TableDeploy{
func registerCell(_ table:UITableView, with cellId:String,and cellHeight:CGFloat){
table.register(cellType.classForCoder(), forCellReuseIdentifier: cellId)
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = cellHeight
}
}
泛型协议TableDeploy
关联了UITableView
所需要的数据源和cell,并通过默认实现配置去注册cell并实现cell高度自适应。注意此处cellType被限定为UITableViewCell的子类,省去了一些不必要的麻烦。
extension ViewController:UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = table.dequeueReusableCell(withIdentifier: cellId) as? cellType{
//to do...
return cell
}
return UITableViewCell()
}
}
UITableViewDataSource
协议的实现就精简了许多。
import UIKit
class ViewController: UIViewController,TableDeploy{
@IBOutlet weak var table: UITableView!
typealias cellType = UITableViewCell
typealias dataType = String
var dataSource: [dataType] = []{
didSet{
table.reloadData()
if table.numberOfRows(inSection: 0) > 0 {
table.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
}
}
let cellId = "cellid"
override func viewDidLoad() {
super.viewDidLoad()
registerCell(table, with: cellId, and: 120)
dataSource = (1...100).map{String($0)}
}
}
因为不能在extension里添加储存属性,所以在controller还是要管着一个数据源。除此之外,只需要拖根线进来绑定tableview就好了。