UITableView应该是 iOS开发中最常用的页面布局方式,每个界面都要写UITableViewDataSource,UITableViewDelegate 实在太繁琐了,PubTableViewInfo让你写界面轻松绘制cell,再也不用写一大堆重复代码了。
一、使用方法
初始化tableviewInfo,内部会初始化tableview
lazy var tableViewInfo:PubTableViewInfo = {
let info = PubTableViewInfo()
self.view.addSubview(info.tableView)
info.tableView.snp.makeConstraints { make in
make.left.bottom.right.equalTo(0)
make.top.equalTo(88)
}
return info
}()
添加cell
// 1.创建一个 sectionModel
let section1 = PubSectionModel.defaultSection()
// 画一个view 当做一个cell
section1.addCell(PubCellModel.createWithViewCell(color: .red, height: 100, viewDefine: { view in
let label = UILabel.init()
label.backgroundColor = .green
label.text = "hello swift"
view.addSubview(label)
label.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}))
// 添加多个规则 cell
section1.addCells(Array<Any>.arrayWithClassName(NSStringFromClass(CustomCell.self), height: 0, models: getModels()))
//添加一个cell 并且添加cell点击事件
let cell = PubCellModel.initCellModel(className: NSStringFromClass(CustomCell.self), height: 0, model: CustomModel()).defaultClickCell({ cellModel in
let cModel = cellModel.getModel() as? CustomModel
print("---- \(cModel?.name ?? "")")
})
section2.addCell(cell)
// 3.刷新列表
tableViewInfo.resetDataList([section1,section2])
数据展示,其中CustomModel是自定义数据模型
override func setModel(_ model: PubCellModel) {
super.setModel(model)
let cModel = model.getModel() as? CustomModel
titleLabel.text = cModel?.name ?? "defautName"
}
完成布局。
内部支持两种cell,使用带类名称初始化方法时,必须继承PubBaseTableViewCell,一般用在用在一些复杂的、数据是列表、带点击事件的cell。
/// 初始化cellModel
/// - Parameters:
/// - className: 类名称
/// - height: 高度 自适应模式 高度无效
/// - model: 数据源
public static func initCellModel(className:String,height:CGFloat,model:Any)->PubCellModel {
let data:Dictionary<String,Any> = ["model":model]
let cellModel = self.init(className: className, height: height, data: data)
return cellModel
}
另外一种是PubCreateViewCell,任何view都可以包装成该cell,用于绘制简单的没有点击事件的cell,比如画一条横线、画一个占位空白cell
//创建一个CellModel 传入一个view 生成特定的PubCreateViewCell
public static func createWithViewCell(_ view:UIView,color:UIColor?,height:CGFloat) -> PubCellModel {
let data:Dictionary<String,Any> = ["view":view]
let cellModel = PubCellModel.init(className:NSStringFromClass(PubCreateViewCell.self), height: height, data: data)
cellModel.backColor = color
return cellModel
}
//创建一个CellModel 免写View 生成特定的PubCreateViewCell
public static func createWithViewCell(color:UIColor?,height:CGFloat,viewDefine:(UIView)->Void)->PubCellModel {
let view = UIView.init(frame:CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: height))
viewDefine(view)
let cellModel = self.createWithViewCell(view, color: color, height: height)
return cellModel
}
二、简单介绍下原理
PubCellModel (NSObject)持有UITableviewCell 类名className、数据model、事件block。一个数据model对应一个PubCellModel
//cell类名
public var className:String = ""
//数据集合
public lazy var data:Dictionary<String,Any> = [:]
//点击事件集合
public lazy var clickEvents:Dictionary<String,Any> = [:]
PubSectionModel(NSObject)持有PubCellMode数组、headerView、footerView
public var headerView:UIView?
public var footerView:UIView?
//cellModel列表
public lazy var rowList:[PubCellModel] = []
PubTableViewInfo(NSObject)持有UITableView,PubSectionModel数组,实现UITableViewDataSource协议
// MARK: -UITableViewDataSource
extension PubTableViewInfo:UITableViewDataSource {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionModel = dataList[section]
return sectionModel.count
}
public func numberOfSections(in tableView: UITableView) -> Int {
return dataList.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = getCellModelWithIndexPath(indexPath)
let cls = NSClassFromString(model.className) as? PubBaseTableViewCell.Type
if cls != nil {
let cell = cls!.initCell(model: model, tableView: tableView)
return cell
}
return UITableViewCell()
}
}
PubBaseTableViewNormalDelegate 实现UITableViewDelegate 协议,固定高度
PubBaseTableViewEstimatedDelegate 实现UITableViewDelegate 协议,自适应高度
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let model = getCellModelWithIndexPath(indexPath)
let clickCell = model.clickEvents[clickCellAction] as? ClickCell
if let click = clickCell {
click(model)
return
}
let clickEvent = model.clickEvents[clickEventAction] as? ClickEventAction
if let click = clickEvent {
click(model,indexPath)
}
}
public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let sectionModel = dataList[section]
if let view = sectionModel.headerView {
return view
}
return UIView.init()
}
public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let sectionModel = dataList[section]
if let view = sectionModel.footerView {
return view
}
return UIView.init()
}
public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
let sectionModel = dataList[section]
return sectionModel.headerHeight
}
public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
let sectionModel = dataList[section]
return sectionModel.footerHeight
}
UICollectionView同理,欢迎交流。