知識(shí)點(diǎn)
- 給tableview添加command綁定支持的分類(lèi)方法
- [RACSignal merge:]操作
- RACTuple使用,快速包裝數(shù)據(jù),快速提取數(shù)據(jù),容錯(cuò)能力強(qiáng)可存放nil
界面如下
- 上拉加載更多 下拉刷新
- 點(diǎn)擊按鈕選擇 底部view根據(jù)選擇情況作出響應(yīng)
- 案例代碼https://git.coding.net/codingheew/RACComand.git
https://github.com/heeween/RACComand.git
ReactiveCocoa用法示例(一).gif
RACComand與TableView刷新事件綁定
- 寫(xiě)UITableView支持RACComand事件綁定的分類(lèi)
// UITableView+RACCommandSupport.m 文件中代碼
- (void)setRac_Refreshcommand:(RACCommand *)command {
objc_setAssociatedObject(self, UITableViewRACRefreshCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (command == nil) return;
__weak typeof(self) weakSelf = self;
self.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
__strong typeof(self) self = weakSelf;
[command execute:self];
}];
}
這里的分類(lèi)主要就是給Tableview增加MJRefresh,并且將傳入command參數(shù)傳入MJRefresh執(zhí)行的block中
- viewmodel中定義刷新和加載更多的事件
//CCOrderViewModel.m 文件中代碼
NSArray *array = @[
@{@"time":@"今天 17:00",@"startAddress":@"浙江吉利控股集團(tuán)有限公司",@"endAddress":@"瑞立東方花城",@"billPrice":@241.00},
@{@"time":@"今天 17:00",@"startAddress":@"浙江吉利控股集團(tuán)有限公司",@"endAddress":@"杭州濱江區(qū)星光大道",@"billPrice":@21.00},
@{@"time":@"今天 17:00",@"startAddress":@"浙江吉利控股集團(tuán)有限公司",@"endAddress":@"杭杭州蕭山國(guó)際機(jī)場(chǎng)",@"billPrice":@10.00},
@{@"time":@"今天 17:00",@"startAddress":@"浙江吉利控股集團(tuán)有限公司",@"endAddress":@"紅石中央大廈",@"billPrice":@19.24},
@{@"time":@"今天 17:00",@"startAddress":@"浙江吉利控股集團(tuán)有限公司",@"endAddress":@"杭州半山國(guó)家森林公園",@"billPrice":@2.00},
@{@"time":@"今天 17:00",@"startAddress":@"浙江吉利控股集團(tuán)有限公司",@"endAddress":@"瑞立東方花城",@"billPrice":@15.00},
@{@"time":@"今天 17:00",@"startAddress":@"浙江吉利控股集團(tuán)有限公司",@"endAddress":@"瑞立東方花城",@"billPrice":@241.00},];
NSMutableArray *modelArray = [NSMutableArray array];
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[modelArray addObject:[CCOrderModel orderWith:obj]];
}];
@weakify(self);
self.refreashCmd = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@strongify(self);
[self.orderArray removeAllObjects];
[self.orderArray addObjectsFromArray:modelArray];
[subscriber sendNext:self.orderArray];
[subscriber sendCompleted];
return nil;
}];
}];
self.loadMoreCmd = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@strongify(self);
[self.orderArray addObjectsFromArray:modelArray];
[subscriber sendNext:self.orderArray];
[subscriber sendCompleted];
return nil;
}];
}];
這里定義兩個(gè)command,將數(shù)據(jù)包在signal中,再包在command中
- 控制器中將viewmode的command事件和UItableview綁定
控制器中的綁定就非常簡(jiǎn)單,這樣綁定之后,tableview的刷新事件就會(huì)進(jìn)入viewmodel的command的block中
// ViewController.m 文件中代碼 command綁定
self.tableView.rac_Refreshcommand = self.viewModel.refreashCmd;
self.tableView.rac_Dropcommand = self.viewModel.loadMoreCmd;
- 給viewmodel添加兩個(gè)刷新事件組合之后的,tableview刷新signal
目的是在控制器,只需要監(jiān)聽(tīng)viewmodel的一個(gè)signal,可以統(tǒng)一刷新tableview
//CCOrderViewModel.m 文件中代碼
RACSignal *refreshEndSignal = [[self.refreashCmd executionSignals] switchToLatest];
RACSignal *loadmoreEndSignal = [[self.loadMoreCmd executionSignals] switchToLatest];
// 上拉和下拉兩個(gè)信號(hào)統(tǒng)一輸出
self.reloadTableViewSignal = [RACSignal merge:@[refreshEndSignal, loadmoreEndSignal]];
- 控制器綁定Signal的代碼
這里是利用rac_liftSelector將viewmodel刷新signal直接和控制器的reloadTableView:綁定
// ViewController.m 文件中代碼
[self rac_liftSelector:@selector(reloadTableView:) withSignals:self.viewModel.reloadTableViewSignal, nil];
/** 刷新列表 */
- (void)reloadTableView:(id)obj {
[self.tableView.mj_header endRefreshing];
[self.tableView.mj_footer endRefreshing];
[self.tableView reloadData];
NSString *numberString = self.viewModel.selectedOrders.first;
NSString *priceString = self.viewModel.selectedOrders.second;
BOOL enable = [self.viewModel.selectedOrders.third boolValue];
self.bottomView.totalPriceLabel.text = priceString;
self.bottomView.totalTravelLabel.text = numberString;
[self.bottomView subviewEnable:enable];
}
- 其他cell賦值就很簡(jiǎn)單了
在這里我說(shuō)下我對(duì)cell創(chuàng)建的理解,我認(rèn)為cell不應(yīng)該持有model.cell賦值就通過(guò)暴露出來(lái)的UI控件在控制器中賦值就好了.這樣cell是一個(gè)很純凈的cell.沒(méi)有任何邏輯.內(nèi)聚性很強(qiáng).邏輯方面的bug也絕對(duì)不需要去cell中找.
MVVM的架構(gòu)模式,就是極大的提高viewmodel層邏輯代碼的內(nèi)聚性,使得UI代碼和業(yè)務(wù)代碼完全隔離,維護(hù)的時(shí)候很專(zhuān)心的去對(duì)應(yīng)的文件找問(wèn)題就可以了.通過(guò)事件綁定在控制器中.極大的簡(jiǎn)化控制器,控制器只存在業(yè)務(wù)代碼的調(diào)度,非常方便找到對(duì)應(yīng)的業(yè)務(wù)代碼.