ReactiveCocoa用法示例(一)

知識(shí)點(diǎn)

  • 給tableview添加command綁定支持的分類(lèi)方法
  • [RACSignal merge:]操作
  • RACTuple使用,快速包裝數(shù)據(jù),快速提取數(shù)據(jù),容錯(cuò)能力強(qiáng)可存放nil

界面如下

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ù)代碼.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容