好久沒有寫東西了特碳,今天來分享一下最近在項(xiàng)目中對(duì)UITableView的一種優(yōu)化寫法诚亚。
先來看一下效果
上面這個(gè)頁面對(duì)應(yīng)的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 {
/*
關(guān)于事件處理:
1、建議項(xiàng)目用路由午乓,cell的事件直接在cell內(nèi)部處理掉站宗。
2、如果不用路由益愈,如果cell上有個(gè)button什么的梢灭,點(diǎn)擊要處理夷家,可以在cell的view model里面聲明對(duì)應(yīng)的RACSignal。再進(jìn)行訂閱敏释。點(diǎn)擊button的時(shí)候库快,發(fā)送事件就可以處理了。
3钥顽、cell的點(diǎn)擊處理還可以用下面的這個(gè)didSelectRow來處理义屏。
*/
self.tableView.didSelectRow = ^(id viewModel, NSString *sectionKey) {
// 點(diǎn)擊事件在這里處理
};
}
#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
適用場(chǎng)景
任何用tableView的地方都可以用。
一般的開發(fā)寫法
要在ViewController里面引入所有類型的cell蜂大,在cellForRow方法里面使用闽铐。注冊(cè)cell使用。heightForRow方法也是各種判斷(前面寫了一篇文章減少判斷的【iOS開發(fā)】UITableView和UICollectionView多種類型cell處理奶浦,更好地組織代碼),增加或者減少某個(gè)類型的cell的時(shí)候兄墅,得去ViewController里面的好幾個(gè)地增加或者減少代碼。
YTTableView
優(yōu)點(diǎn)
完全解耦cell和view controller澳叉。
方便版本迭代:新版本有新的樣式或是要添加新的section 什么的隙咸,都可以不用改動(dòng)viewController。
cell有極高的可重用性成洗,實(shí)現(xiàn)了對(duì)應(yīng)的協(xié)議后五督,任何地方都可以用。
不需要修改ViewController里面的代碼泌枪。
任何的修改都可以在一個(gè)地方完成概荷。
集成了table view的分隔線秕岛,可以任意調(diào)整分隔線碌燕。section的第一條和最后一條分隔線可以分開設(shè)置。
cell的事件處理
- 建議項(xiàng)目用路由继薛,cell的事件直接在cell內(nèi)部處理掉修壕。
- 如果不用路由,如果cell上有個(gè)button什么的遏考,點(diǎn)擊要處理慈鸠,可以在cell的view model里面聲明對(duì)應(yīng)的RACSignal。再進(jìn)行訂閱灌具。點(diǎn)擊button的時(shí)候青团,發(fā)送事件就可以處理了。
- cell的點(diǎn)擊處理還可以用YTTableView暴露的didSelectRow來處理咖楣。
集成使用
把YTTableView相關(guān)代碼拉到項(xiàng)目中督笆,pod支持找時(shí)間加上去。
注意的點(diǎn):
如果用YTTableView中的自定義的分隔線诱贿,記得把table view本來的分隔線去掉娃肿。
cell都要有一個(gè)對(duì)應(yīng)的cell view model咕缎。
cell 要實(shí)現(xiàn)YTCellProtocol協(xié)議。
cell view model 要實(shí)現(xiàn) YTTableCellViewModelProtocol協(xié)議料扰。
協(xié)議說明
- YTCellProtocol
table view的cell都要實(shí)現(xiàn)這個(gè)接口凭豪,接口提供配置數(shù)據(jù)的方法和注冊(cè)cell的方法。
/**
cell 的接口
提供一個(gè)配置cell的ViewModel的方法
*/
@protocol YTCellProtocol <NSObject>
@required
/**
通過 view model 來配置cell, table view 的數(shù)據(jù)源里面裝的都會(huì)是 view model
@param viewModel cell 對(duì)應(yīng)的 view model
*/
- (void)configCellWithViewModel:(id)viewModel;
@end
- YTTableCellViewModelProtocol
table view cell 對(duì)應(yīng)的view model 都要實(shí)現(xiàn)這個(gè)接口晒杈,實(shí)現(xiàn)返回cell高度的方法和cell的復(fù)用id
/**
UITableViewCell 對(duì)應(yīng)的ViewModel 的協(xié)議
*/
@protocol YTTableCellViewModelProtocol <NSObject>
@required;
/**
返回cell的高度, 這個(gè)方法是在view model中實(shí)現(xiàn)嫂伞,view model中有cell的全部數(shù)據(jù),所以這里可以通過數(shù)據(jù)計(jì)算高度桐智,或者直接返回固定高度
@return cell的高度
*/
- (CGFloat)cellHeight;
/**
返回cell的復(fù)用id
@return cell的復(fù)用id
*/
+ (NSString *)identifier;
/**
注冊(cè)cell
@param table 要注冊(cè)到的table view
*/
+ (void)registerFor:(UITableView *)table;
@end
Section類說明
@interface YTTableViewSection : NSObject
/**
用來標(biāo)識(shí)section的類型末早,要保證每個(gè)section的都不同
代理方法里面如果要做特殊處理會(huì)用到,所以不能相同
*/
@property (nonatomic, copy) NSString *sectionKey;
/**
section 里面 row 的 view model 集合
*/
@property (nonatomic, copy) NSArray *viewModels;
/**
返回這個(gè)section有多少row说庭,這個(gè)不用設(shè)置然磷,在設(shè)置viewModels時(shí),會(huì)自動(dòng)設(shè)置
*/
@property (nonatomic, readonly) NSInteger numberOfRows;
/**
是否自動(dòng)添加分隔線
*/
@property (nonatomic) BOOL autoSeparator;
// 分隔線顏色 默認(rèn):#E6E6E6
@property (nonatomic, strong) UIColor *separatorColor;
@property (nonatomic, strong) UIColor *separatorBackgroundColor;
// 分隔線左邊縮進(jìn)
@property (nonatomic) CGFloat separatorLeftInset;
// 分隔線右邊縮進(jìn)
@property (nonatomic) CGFloat separatorRightInset;
// 分隔線的高度 默認(rèn)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;
Cocoapods支持
如果覺得可以就給個(gè)Star刊驴。
Github Repo