基于reactive cocoa的MVVM练习

首先说明,代码来自老司机,_

使用cocoa pods集成,2.5版本以上是swift语言,

pod 'ReactiveCocoa', '~> 2.5' #

对MVVM的介绍学习http://www.jianshu.com/p/87ef6720a096 讲的比较详细
话不多说 直接上代码
1.viewController中 代码就剩这么点


#import "MsgModelController.h"
#import "MsgTableView.h"
#import "MsgViewModel.h"
@interface MsgModelController ()
@property(nonatomic,strong)MsgTableView *msgView;
@property(nonatomic,strong)MsgViewModel *viewModel;
@end

@implementation MsgModelController


- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.navigationItem.titleView = [[navLabel alloc] initWithFrame:lableFrame titile:@"选择模板"];
    self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithImage:@"btn_back.png" target:self action:@selector(popLeftBtnClick)];//以上初始化导航栏
  
    [self bindViewModel];
}
-(void)bindViewModel{
    
    self.msgView = [[MsgTableView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:self.msgView];
//    绑定数据
    RAC(self.msgView,dataList)  = RACObserve(self.viewModel, dataList);
    //执行命令
    [self.viewModel.loadCommand execute:self.msgView];//把TableView传入viewModel
}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.tabBarController.tabBar.hidden = YES;
}

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    self.tabBarController.tabBar.hidden = NO;
}
-(void)popLeftBtnClick{
    [self.navigationController popViewControllerAnimated:YES];
}

-(MsgViewModel*)viewModel{
    if (!_viewModel) {
        _viewModel = [[MsgViewModel alloc] init];
        _viewModel.nav = self.navigationController;
    }
    return _viewModel;
}
@end

2.viewModel

.h
@interface MsgViewModel : NSObject
//加载数据
@property(nonatomic,strong)RACCommand   *loadCommand;
@property(nonatomic,strong)NSMutableArray *dataList;
//底部按钮
@property(nonatomic,strong)RACCommand   *btnCommoand;

@property(nonatomic,strong)UINavigationController *nav;
@end

.m
#import "MsgViewModel.h"
#import "MsgTableView.h"
#import "NewModelViewController.h"
@implementation MsgViewModel
-(instancetype)init{
    self = [super init];
    if (self) {
        [self initViewModel];
    }
    return self;
}

-(void)initViewModel{
    //加载数据
    self.loadCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        NSData *data=[[NSUserDefaults standardUserDefaults]objectForKey:UserKey];
        UserInfoSaveModel * userInfoModel=[NSKeyedUnarchiver unarchiveObjectWithData:data];
        NSArray *dataArray = [[NSArray alloc] initWithObjects:[NSString stringWithFormat:@"%d",0],[NSString stringWithFormat:@"%d",10],nil];
        NSString *hmacString = [[communcat sharedInstance] ArrayCompareAndHMac:dataArray];
        
        In_informModel *inModel= [[In_informModel alloc] init];
        inModel.key = userInfoModel.key;
        inModel.digest = hmacString;
        inModel.offset = [NSString stringWithFormat:@"%d",0];
        inModel.page_size = [NSString stringWithFormat:@"%d",10];
      
        NSMutableDictionary *indic = [[NSMutableDictionary alloc]init];
        [indic setObject:inModel.key forKey:@"key"];
        [indic setObject:inModel.digest forKey:@"digest"];
        [indic setObject:inModel.offset forKey:@"offset"];
        [indic setObject:inModel.page_size forKey:@"page_size"];
        
        NSString *url=[NSString stringWithFormat:@"%@/crowd-sourcing-consumer/api/v2/requirement/get/message/list",kUrlTest];
        RACSignal *signal = [BBJDRequestManger postWithURL:url withParamater:indic];//加载网络请求的数据  对AFNetworking的封装
        [signal subscribeNext:^(id x) {
            MsgTableView   *msgView = input;//接收传入的tableview
            NSArray *result = x[@"data"][@"messages"];
            for (NSDictionary *dict in result) {
                Out_informBody *  informBody = [[Out_informBody alloc]initWithDictionary:dict error:nil];
                [self.dataList addObject:informBody.msg ];
            }
            [msgView.tableView reloadData];
        }];
        return signal;
    }];
    
    self.btnCommoand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        UIViewController *vc = (UIViewController*)input;
        NewModelViewController *newVC = [[NewModelViewController alloc] init];
        CATransition *transition = [CATransition animation];
        transition.duration = 0.5f;
        transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
        transition.type = kCATransitionReveal;
        [vc.navigationController.view.layer addAnimation:transition forKey:nil];
        [vc.navigationController pushViewController:newVC animated:YES];
        return [RACSignal empty];
    }];
}
-(NSMutableArray*)dataList{
    if (!_dataList) {
        _dataList = [NSMutableArray array];
    }
    return _dataList;
}
@end

3.对view

view1  
.h
@interface MsgModelViewCell : UITableViewCell
@property(nonatomic,assign)CGFloat cellHeight;
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
-(void)cellAutoLayoutHeight:(NSString *)text;
@end

.m
@interface MsgModelViewCell()

@property(nonatomic,strong)UILabel *label;

@end

@implementation MsgModelViewCell

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
  self =  [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        _label = [[UILabel alloc] init];
        _label.font = MiddleFont;
        _label.numberOfLines = 0;
        _label.textColor = [UIColor blackColor];
        [self.contentView addSubview:_label];
       
        
    }
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    return self;
}

-(void)cellAutoLayoutHeight:(NSString *)text{
    
    self.label.text =  text;
    
    CGSize maxSize = CGSizeMake(SCREEN_WIDTH-40, MAXFLOAT);
    // 2.计算文字的高度
    CGFloat textH = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14]} context:nil].size.height;
    self.label.frame = CGRectMake(20, 15, SCREEN_WIDTH-40, textH);
    [self.label sizeToFit];
    
    _cellHeight = self.label.height +30;

}

- (void)awakeFromNib {
    [super awakeFromNib];
   
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end
view2
.h
 @interface MsgTableView : UIView
@property(nonatomic,strong)MsgViewModel *model;
@property(nonatomic,strong)UITableView *tableView;
@property(nonatomic,strong)NSMutableArray *dataList;
@property(nonatomic,strong)UILabel *showLabel;
@property(nonatomic,strong)UIButton *bottomBtn;

@end

.m
static NSString *CELLID = @"reuseIdentifier";
@interface MsgTableView()

@end

@implementation MsgTableView

-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self initSubViews];
    }
    return self;
}

-(void)initSubViews{
    [self addSubview:self.tableView];
    [self addSubview:self.bottomBtn];
  
    
}

#pragma mark---------tableViewDelegate----------

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return self.dataList.count;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 1;
}

-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    
    if (section == 0) {
        return self.showLabel;
    }else{
        return nil;
    }
}

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    if (section == 0) {
        return 30;
    }else{
        return 10;
    }
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    MsgModelViewCell *cell = [[MsgModelViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELLID];
    [cell cellAutoLayoutHeight:self.dataList[indexPath.section]];
    return cell.cellHeight;
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    MsgModelViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CELLID];
    if (!cell) {
        cell  = [[MsgModelViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELLID];
    }
    [cell cellAutoLayoutHeight:self.dataList[indexPath.section]];
    return cell;
}

#pragma mark -----懒加载-----
- (UITableView *)tableView
{
    return HT_LAZY(_tableView, ({
        UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0,0, SCREEN_WIDTH, SCREEN_HEIGHT-44-20) style:UITableViewStylePlain];
        tableView.separatorStyle =  UITableViewCellSeparatorStyleNone;
        tableView.delegate = self;
        tableView.dataSource = self;
        tableView.backgroundColor = [UIColor colorWithRed:0.9608 green:0.9608 blue:0.9608 alpha:1.0];
        tableView;
    }));
}

-(UILabel*)showLabel{
    return HT_LAZY(_showLabel, ({
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 30)];
        label.text = @"说明:已通过审核的模板可能会根据当前政策变化被禁用";
        label.textColor = [UIColor redColor];
        label.font = [UIFont systemFontOfSize:12];
        label.textAlignment = 1;
        label.backgroundColor = [UIColor colorWithRed:0.9608 green:0.9608 blue:0.9608 alpha:1.0];
        label;
    }));
}

-(UIButton*)bottomBtn{
    return HT_LAZY(_bottomBtn, ({
        UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0,SCREEN_HEIGHT-44-64, SCREEN_WIDTH,44)];
        [btn setTitle:@"新增模板" forState:UIControlStateNormal];
        btn.titleLabel.font = [UIFont systemFontOfSize:18];
        btn.backgroundColor = MAINCOLOR;
        [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
    
            [self.model.btnCommoand execute:[self currentViewController]];///按钮绑定方法  并将当前控制器传入到viewModel方法中
        }];
        btn;
    }));
}
//获取当前控制器
-(UIViewController *)currentViewController{
    UIViewController *vc;
    for (UIView* next = [self superview]; next; next = next.superview) {
        UIResponder* nextResponder = [next nextResponder];
        if ([nextResponder isKindOfClass:[objc_getClass("UIViewController") class]] ) {
            vc = (UIViewController*)nextResponder;
            return vc;
        }
    }
    return vc;
}

-(NSMutableArray*)dataList{
    return HT_LAZY(_dataList, ({
        NSMutableArray *array = [NSMutableArray array];
        array;
    }));
}

-(MsgViewModel*)model{
    if (!_model) {
        _model = [[MsgViewModel alloc] init];
    }
    return _model;
}



@end

用到的宏定义

#define HT_LAZY(object, assignment) (object = object ?: assignment)
//屏幕宽度和高度
#define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width
#define SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height

你可能感兴趣的:(基于reactive cocoa的MVVM练习)