iOS 简单的MVVM + RAC

作者: Wy_chris | 来源:发表于2017-03-23 11:54 被阅读171次

    简单的尝试一下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 需要做哪几件事情 :

    • 1 网络请求 数据更新
    • 2 处理UItableviewCell 的点击事件

    声明两个处理事件的对象

    /** 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和资料,深点的还不太懂, 很多类还没有尝过,需要多多尝试。

    参考链接:

    相关文章

      网友评论

        本文标题:iOS 简单的MVVM + RAC

        本文链接:https://www.haomeiwen.com/subject/qgjznttx.html