RN/链式编程/函数式编程/以及其他新兴的技术面试题程序员

iOS 简单的MVVM + RAC

2017-03-23  本文已影响171人  Wy_chris

简单的尝试一下MVVM + RAC ,这个东西用过的都说好。 VC 控制在200行不是梦。 启动的VC不用管,直接点击屏幕进第二个控制器就好
https://git.oschina.net/wyChirs/MVVM-RAC.git

MVVM.gif
1.先创建好VC ViewModel View 各自的类

我把UITableView 页抽出来,自定义了一个。外加一个HeadView。主要完成数据的绑定,加载,更新(MJRefresh)

在UITableView的初始化方法中 设置代理,上下拉刷新等

-(instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
    self = [super initWithFrame:frame style:style];
    
    if (self) {
        self.dataArray = [NSMutableArray array];
        self.page      = 1;
        self.delegate  = self;
        self.dataSource = self;
        self.tableHeaderView = self.headView;
        
        self.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(refresh)];
        self.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)];
        self.mj_footer.automaticallyHidden = YES;  
    }
    return self;
}

上下拉刷新的方法(控制分页)

-(void)refresh{
   self.page = 1;
  //该方法是执行  refreshCommand 事件   @[self,@(self.page)]  传递的参数  执行该方法后  会触发VM 的 refreshCommand  事件, 并且在取得参数时是按照数组下标对应获取   
   [self.viewModel.refreshCommand execute:@[self,@(self.page)]];
}
-(void)loadMoreData{
   self.page++;
   [self.viewModel.refreshCommand execute:@[self,@(self.page)]];
}

在自定义的TableView中 Cell 的点击事件


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
   // 执行 itemClickCommand   传入参数 
    [self.viewModel.itemClickCommand execute:@[[NSNumber numberWithInteger:indexPath.row],self.headView]];
}
2.最主要的就是 VM的创建

首先确定VM 需要做哪几件事情 :

声明两个处理事件的对象

/** cell 点击事件 */
@property(nonatomic,strong)RACCommand *itemClickCommand;
/** 刷新数据 */
@property(nonatomic,strong)RACCommand *refreshCommand;
//RACCommand RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。

声明 数据源和分页

@property(nonatomic,strong)NSMutableArray *data;
@property(nonatomic,assign)NSInteger page;

初始化事件 并绑定数据

-(void)initViewModel{
    
    @weakify(self);
    
    self.refreshCommand  =  [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        @strongify(self)
        //此处  网络请求获取数据源  上下拉刷新更新数据源
        self.page = [input[1] integerValue];

        if (self.page == 1) {
            [self.data removeAllObjects];
        }
        
        for (NSInteger i = 0; i< 5; i++) {
            
            NSDictionary *dic = @{@"name":[NSString stringWithFormat:@"第%ld页怪兽",self.page],@"age":@(i+20)};
            Model  *mod = [[Model alloc] initWithDictionary:dic];
            
            [self.data addObject:mod];
        }
        
        TableView *tableView = input[0];
        [tableView reloadData];
        
        [tableView.mj_header endRefreshing];
        [tableView.mj_footer endRefreshing];
        
        return [RACSignal empty];
    }];
    
    self.itemClickCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        @strongify(self)
        
        HeadView * view  = input[1];
        
        NSInteger index  =  [input[0] integerValue];
        Model *mod = self.data[index];
        
        view.bgLabel.text = [NSString stringWithFormat:@"--%@:  %ld岁--",mod.name,mod.age];
        
        return [RACSignal empty];
    }];  
![MVVM.gif](http:https://img.haomeiwen.com/i1711499/b8eeebb6add0a61d.gif)
}

最后就是在VC中 绑定VM

//最后的VC 仅仅只有50行代码 所有的业务逻辑,网络请求都已经放在了VM中进行。
@interface TestViewController ()

@property(nonatomic,strong) TableView *tableView;
@property(nonatomic,strong) ViewModel *viewModel;

@end

@implementation TestViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.viewModel = [ViewModel new];
    
    [self bindViewModel];
    
    [self.view addSubview:self.tableView];
    
}

-(void)bindViewModel{
    
    //KVO 形式  动态监测 数组和 页数
    RAC(self.tableView,dataArray) = RACObserve(self.viewModel, self.data);
    RAC(self.tableView,page)      = RACObserve(self.viewModel, self.page);
    
    [self.viewModel.refreshCommand execute:@[self.tableView,@(1)]];
}

-(TableView*)tableView{

    if (!_tableView) {
        _tableView = [[TableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
        
        _tableView.viewModel = self.viewModel;
        
    }
    return _tableView;
}

随便看了一点别人的demo和资料,深点的还不太懂, 很多类还没有尝过,需要多多尝试。

参考链接:

上一篇下一篇

猜你喜欢

热点阅读