github仓库地址 https://github.com/gaoyangclub/GYTableViewController
前言
TableView是在项目开发的时候经常用到的组件,几乎百分之八十以上的页面都需要使用,一个最基本的Table需要实现DataSource的协议才能成功展示;那么当页面越来越多,根据不同的业务场景就需要实现不同的协议,将会出现不少相似冗余代码;当需求改变后,某些复杂页面的排版和业务需求耦合在一起,后期将变得越来越难以维护;大部分情况下,Table需要和下拉刷新上拉加载控件配合使用模拟网络请求;为了满足项目的可维护性,将UI排版和业务需求剥离出来,且自带一些常用的功能,GYTableViewController系列应运而生。
技术特点
- 无需继承自定义类,引入头文件UIViewController+GYTableView.h即可使用
- 支持OC和Swift(混合)
- Section和Cell层次更加清晰,根据传入的Section数据结构内部已经全部实现Section和Cell相关delegate方法
- Cell实例可获得外部动态数据,索引位置,上下关系,选中状态等,随时更换样式
- 自带MJRefresh框架,提供下拉刷新和上拉加载功能
- 提供Section,Cell间距设置,提供选中行高亮、选中行自动居中,提供设置Cell动态高度设置等API
- 框架中的元素全部继承于原生的tableView,除部分代理方法外,其他原生方法扔然可以使用
安装方法
- pod安装: pod ‘GYTableViewController’
- 手动安装:手动安装需要添加两个库,将GYTableViewController项目文件中Framework文件下的文件导入自身项目,同时此框架基于MJRefresh,所以也需要导入MJRefresh框架文件,手动或者pod都可以,MJRefresh安装方法请戳
- demo项目图标基于iconfont技术栈,请戳这里
框架用法
请使用该框架中的元素来代替原生Table控件,对应关系如下:
UIViewController+GYTableView -> UIViewController
GYTableBaseView -> UITableView
GYTableViewCell -> UITableViewCell
GYTableViewSection 原生使用UIView展示section内容,这里使用GYTableViewSection
SectionNode 用来设置Section样式与GYTableViewSection实例绑定
CellNode 用来设置Cell样式与GYTableViewCell实例绑定
使用时有Table控件的界面直接引入头文件UIViewController+GYTableView.h即可,.h示例如下
- Objective-C
#import "UIViewController+GYTableView.h"
@interface YourViewController : UIViewController
swift项目在Bridging_Header桥接文件中引入UIViewController+GYTableView.h,参照demo示例
.m或swift实现文件必须开启gy_useTableView开关来使用Table控件GYTableView
- Objective-C
- (BOOL)gy_useTableView {
return YES;
}
- Swift
override func gy_useTableView() -> Bool {
return true
}
.m或swift文件中重写headerRefresh添加元素,当自带的下拉刷新控件下拉时调用;从而开始Table内容层次搭建,以及各种类型的Cell位置如何摆放等
- (void)headerRefresh:(GYTableBaseView *)tableView {
//下拉刷新后开始请求后台提供数据,请求到数据后根据解析的内容展开cell实例和位置等操作,代码结构如下(伪代码)
request {
tableView {
sectionNode {
cellNode,
cellNode,
...
}
sectionNode {
cellNode,
...
}
...
}
[tableView headerEndRefresh:YES];//界面搭建完毕后停止刷新
}
}
Cell控件直接继承GYTableViewCell,.h示例如下
- Objective-C
#import "GYTableViewCell.h"
@interface YourViewCell : GYTableViewCell
- Swift
class YourViewCell: GYTableViewCell
.m文件中重写showSubviews方法进行布局,利用getCellData获取Table控件中传入的数据
- Objective-C
- (void)showSubviews {
id yourData = [self getCellData];//先获取外部传入的数据
//开始界面布局...
}
- Swift
override func showSubviews() {
let yourData = self.getData()
//开始界面布局...
}
添加Cell
Table控制器内部实现
- Objective-C
- (void)headerRefresh:(GYTableBaseView *)tableView {
[tableView addSectionNode:[SectionNode initWithParams:^(SectionNode *sNode) {
//添加一个高度为230,类型为BannerViewCell,展示banner图片序列的Cell
[sNode addCellNode:[CellNode initWithParams:230 cellClass:RefreshBannerViewCell.class cellData:Mock.bannerUrlGroup]];
}]];
[tableView headerEndRefresh:YES];//不要忘了结束刷新,否则刷新动画会停留原地
}
- Swift
override func headerRefresh(_ tableView: GYTableBaseView!) {
tableView.add(SectionNode.initWithParams({
sNode in
//添加一个高度为230,类型为BannerViewCell,展示banner图片序列的Cell
sNode?.add(CellNode.initWithParams(230, cellClass: RefreshBannerViewCell.self, cellData: Mock.bannerUrlGroup))
}))
tableView.headerEndRefresh(true)
}
批量添加Cell
Table控制器内部实现(暴力添加,Swift略过…)
- (void)headerRefresh:(GYTableBaseView *)tableView {
[tableView addSectionNode:[SectionNode initWithParams:^(SectionNode *sNode) {
//添加一个高度为230,类型为BannerViewCell,展示banner图片序列的Cell
[sNode addCellNode:[CellNode initWithParams:230 cellClass:RefreshBannerViewCell.class cellData:self.bannerUrlGroup]];
}]];
//注意banner和基金产品列表属于不同区域,应存放到各自section中添加,管理section视图会比较方便
[tableView addSectionNode:[SectionNode initWithParams:^(SectionNode *sNode) {
//添加多个高度为80,类型为RefreshFundViewCell,展示基金信息的Cell
[sNode addCellNode:[CellNode initWithParams:80 cellClass:RefreshFundViewCell.class cellData:self.fundModels[0]]];
[sNode addCellNode:[CellNode initWithParams:80 cellClass:RefreshFundViewCell.class cellData:self.fundModels[1]]];
[sNode addCellNode:[CellNode initWithParams:80 cellClass:RefreshFundViewCell.class cellData:self.fundModels[2]]];
//...
}]];
tableView.headerEndRefresh(true);//不要忘了结束刷新,否则刷新动画会停留原地
}
相同类型的Cell添加可以修改成通过原数组批量添加
- Objective-C
[tableView addSectionNode:[SectionNode initWithParams:^(SectionNode *sNode) {
//添加多个高度为80,类型为RefreshFundViewCell,展示基金信息的Cell
[sNode addCellNodeByList:[CellNode dividingCellNodeBySourceArray:80 cellClass:RefreshFundViewCell.class sourceArray:Mock.fundModels]];
}]];
- Swift
tableView.add(