利用Swift泛型快速写一个上下拉刷新的列表

120 阅读1分钟

定义一个cell绑定model的协议

public protocol CellModelProtocol{
    var cellModel:Codable? {get set}
}

列表基类

DataSource我用的Struce:Codable cell用的Reusable

class SXListVC<DataSourceClass: Codable, CellClass:UITableViewCell>: UIViewController, UITableViewDataSource, UITableViewDelegate where CellClass: CellModelProtocol & Reusable & NibLoadable {

    /// 数据源
    var datas = [DataSourceClass]()

    /// 当前页码
    var current_page: Int = 1

    /// 是否需要下拉刷新
    var isNeedDropdownRefresh = true

    /// 是否需要上拉加载
    var isNeedPullupLoading = true

    let tableView: UITableView = {

        let tableView = UITableView()
        tableView.showsVerticalScrollIndicator = false
        tableView.tableFooterView = UIView()
        tableView.estimatedRowHeight = 135
        tableView.rowHeight = UITableView.automaticDimension
        return tableView
    }()

    override func viewDidLoad() {

        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        view.addSubview(tableView)
        tableView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        if isNeedDropdownRefresh {
            // 下拉刷新
            MJRefreshNormalHeader { [weak self] in
                self?.loadDataAtPage(1)
            }.autoChangeTransparency(true).link(to: tableView)
        }

        if isNeedPullupLoading {
            // 上拉加载
            tableView.mj_footer = MJRefreshAutoNormalFooter(refreshingBlock: {[weak self] in

                if let self {
                    self.loadDataAtPage(self.current_page + 1)
                }
            })
        }

        if isNeedDropdownRefresh {
            tableView.mj_header?.beginRefreshing()
        }
    }

    /// mj_*header、mj_footer 停止刷新*
    func endRefreshing() {

        tableView.mj_header?.endRefreshing()
        tableView.mj_footer?.endRefreshing()
    }

    /// 加载第几页的数据,由子类去实现
    func loadDataAtPage(_ page: Int) {}

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return datas.count}
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        var cell:CellClass = tableView.dequeueReusableCell(for: indexPath)
        cell.cellModel = datas[indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
}

自定义cell实现CellModelProtocol

class HYQListCell: UITableViewCell, NibReusable, CellModelProtocol {
    /// 名字
    @IBOutlet weak var m_userNameLabel: UILabel!
    var cellModel: Codable? {
        didSet {
            guard let obj = cellModel as? NewestListResDataList else {
                return
            }
            m_userNameLabel.text = obj.user_name
        }
    }
}

继承SXListVC,然后你再写一个上下拉刷新的列表就简单了

class HYQListVC: SXListVC<NewestListResDataList, HYQListCell> {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tableView.estimatedRowHeight = 135
        tableView.rowHeight = UITableView.automaticDimension
        tableView.register(cellType: HYQListCell.self)
     }

    override func loadDataAtPage(_ page: Int) {

        NewestListApiLoadingProvider.requestObj(.list(page: page, progress_type: 1)) { (returnData:NewestListRes?, error) in

            self.endRefreshing()
            if let error {
                print(error.localizedDescription)
                return
            }

            if returnData?.code != 1 {
                returnData?.msg.map{print($0)}
                return
            }

            guard let list = returnData?.data?.list else {
                return
            }

            if page == 1 {
                self.datas.removeAll()
            }

            if returnData?.data?.is_next == true {
                self.tableView.mj_footer?.state = .idle
            } else {
                self.tableView.mj_footer?.endRefreshingWithNoMoreData()
            }
            
            self.current_page = page
            self.datas.append(contentsOf: list)
            self.tableView.reloadData()
        }

    }

}