Tableview协议抽取

起因

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就好了。

你可能感兴趣的:(Tableview协议抽取)