好久没有写东西了,今天来分享一下最近在项目中对UITableView的一种优化写法。
先来看一下效果
效果图
上面这个页面对应的ViewController的代码是这样的, Demo地址在文章的末尾:
#import "ViewController.h"
#import "YTTableView.h"
#import "ViewModel.h"
@interface ViewController ()
@property (nonatomic, strong) YTTableView *tableView;
@property (nonatomic, strong) ViewModel *viewModel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
self.tableView.frame = self.view.bounds;
[self bindActions];
self.tableView.sections = self.viewModel.sections;
}
- (void)bindActions {
/*
关于事件处理:
1、建议项目用路由,cell的事件直接在cell内部处理掉。
2、如果不用路由,如果cell上有个button什么的,点击要处理,可以在cell的view model里面声明对应的RACSignal。再进行订阅。点击button的时候,发送事件就可以处理了。
3、cell的点击处理还可以用下面的这个didSelectRow来处理。
*/
self.tableView.didSelectRow = ^(id viewModel, NSString *sectionKey) {
// 点击事件在这里处理
};
}
#pragma mark - lazy load
- (YTTableView *)tableView {
if (!_tableView) {
_tableView = [[YTTableView alloc] init];
_tableView.backgroundColor = [UIColor colorWithRed:0xef/255.0 green:0xef/255.0 blue:0xef/255.0 alpha:1];
_tableView.tableFooterView = [UIView new];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
return _tableView;
}
- (ViewModel *)viewModel {
if (!_viewModel) {
_viewModel = [ViewModel new];
}
return _viewModel;
}
@end
任何用tableView的地方都可以用。
要在ViewController里面引入所有类型的cell,在cellForRow方法里面使用。注册cell使用。heightForRow方法也是各种判断(前面写了一篇文章减少判断的【iOS开发】UITableView和UICollectionView多种类型cell处理,更好地组织代码),增加或者减少某个类型的cell的时候,得去ViewController里面的好几个地增加或者减少代码。
把YTTableView相关代码拉到项目中,pod支持找时间加上去。
注意的点:
/**
cell 的接口
提供一个配置cell的ViewModel的方法
*/
@protocol YTCellProtocol <NSObject>
@required
/**
通过 view model 来配置cell, table view 的数据源里面装的都会是 view model
@param viewModel cell 对应的 view model
*/
- (void)configCellWithViewModel:(id)viewModel;
@end
/**
UITableViewCell 对应的ViewModel 的协议
*/
@protocol YTTableCellViewModelProtocol <NSObject>
@required;
/**
返回cell的高度, 这个方法是在view model中实现,view model中有cell的全部数据,所以这里可以通过数据计算高度,或者直接返回固定高度
@return cell的高度
*/
- (CGFloat)cellHeight;
/**
返回cell的复用id
@return cell的复用id
*/
+ (NSString *)identifier;
/**
注册cell
@param table 要注册到的table view
*/
+ (void)registerFor:(UITableView *)table;
@end
@interface YTTableViewSection : NSObject
/**
用来标识section的类型,要保证每个section的都不同
代理方法里面如果要做特殊处理会用到,所以不能相同
*/
@property (nonatomic, copy) NSString *sectionKey;
/**
section 里面 row 的 view model 集合
*/
@property (nonatomic, copy) NSArray *viewModels;
/**
返回这个section有多少row,这个不用设置,在设置viewModels时,会自动设置
*/
@property (nonatomic, readonly) NSInteger numberOfRows;
/**
是否自动添加分隔线
*/
@property (nonatomic) BOOL autoSeparator;
// 分隔线颜色 默认:#E6E6E6
@property (nonatomic, strong) UIColor *separatorColor;
@property (nonatomic, strong) UIColor *separatorBackgroundColor;
// 分隔线左边缩进
@property (nonatomic) CGFloat separatorLeftInset;
// 分隔线右边缩进
@property (nonatomic) CGFloat separatorRightInset;
// 分隔线的高度 默认1px
@property (nonatomic) CGFloat separatorHeight;
// section头部分隔线 不受separatorInset影响
@property (nonatomic) BOOL sectionTopSeparator;
@property (nonatomic) CGFloat topSeparatorHeight;
@property (nonatomic, strong) UIColor *topSeparatorColor;
// section尾部分隔线 不受separatorInset影响
@property (nonatomic) BOOL sectionBottomSeparator;
@property (nonatomic) CGFloat bottomSeparatorHeight;
@property (nonatomic, strong) UIColor *bottomSeparatorColor;
- (instancetype)initWithSectionKey:(NSString *)key viewModels:(NSArray *)viewModels;
如果觉得可以就给个Star。