UITableview中cell和sectionHeader的复用与解耦

我们通常使用tableview的时候要做一件事
在viewdidload中

        self.tablview.register(cellClass, forCellReuseIdentifier:"cell")
        self.tablview.register(HeaderFooterViewClass, forHeaderFooterViewReuseIdentifier:"header")

然后在

func tableView(_ tableView: UITableView, cellForRowAt indexPath:IndexPath)-> UITableViewCell { 
       let cell = tableView.dequeueReusableCell(withIdentifier: "cell") 
       return cell!
    }


    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
         
            let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header")!
            header.setValue(item, forKey: "model")
            self.registerEventforSectionHeader(header: header,model: item)
            return header 
    }

如果一个列表存在多种cell或者多种header 通常的做法是

func tableView(_ tableView: UITableView, cellForRowAt indexPath:IndexPath)-> UITableViewCell {  
      if  self.dataList[indexPath.row]  is Person {  
              let cell:Cell1 = tableView.dequeueReusableCell(withIdentifier: "cell1") 
              cell.viewModel=self.dataList[indexPath.row] 
              return cell!
        }else  {

              let cell:Cell2 = tableView.dequeueReusableCell(withIdentifier: "cell2")
               cell.viewModel=self.dataList[indexPath.row]  
              return cell!
        }
     
    }

既然数据源是是self.dataList 那么为什么我还要用string作为cell的id来获取cell呢
为什么不使用model的class类型来帮绑定cell和header呢
说干就干
使用swift 的extends 或者oc的category

extension UITableView {
     
    
    func registerCellClass(cellClass:AnyClass,modelClass:AnyClass) {
        self.register(cellClass, forCellReuseIdentifier:String(describing:modelClass.self) )
    }
    func registerCellNib(nib:UINib,modelClass:AnyClass){
        self.register(nib, forCellReuseIdentifier: String(describing:modelClass.self))
    }
    
    ///headerClass必须继承UITableViewHeaderFooterView
    func registerHeaderClass(headerClass:AnyClass,modelClass:AnyClass) {
        self.register(headerClass, forHeaderFooterViewReuseIdentifier: String(describing:modelClass.self))
    }
    func registerHeaderNib(nib:UINib,modelClass:AnyClass){
        self.register(nib, forHeaderFooterViewReuseIdentifier: String(describing:modelClass.self))
    }
}

这样我就能在调用的时候就可以

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

       let item=self.getRealDataSourceModel(indexPath: indexPath)
       let cellKey=String(describing:item.classForCoder.self)
       let cell = tableView.dequeueReusableCell(withIdentifier: cellKey)
       cell?.setValue(item, forKey: "model") 
       return cell!
    }

如果再自己写一个tableviewController的基类
把cell和model数据源的关系绑定好
那么实现一个带列表的界面
heightforIndexpath cellforIndexpath numberOfRow numberOfSection都可以不用写了

只需要注册一下cell和model的关系,传一个dataList进去 一切都做好了

具体例子我已经做出来了可以看看我封装的swift开发框架
https://github.com/manondidi/swiftArch

基类:PagingViewController
demo: PagingOffsetIdDemoViewController和PaingTalbeDemoViewController

你可能感兴趣的:(UITableview中cell和sectionHeader的复用与解耦)