基于reactive cocoa的MVVM練習(xí)

首先說明,代碼來自老司機,_

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

pod 'ReactiveCocoa', '~> 2.5' #

對MVVM的介紹學(xué)習(xí)http://www.lxweimin.com/p/87ef6720a096 講的比較詳細(xì)
話不多說 直接上代碼
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)];//以上初始化導(dǎo)航欄
  
    [self bindViewModel];
}
-(void)bindViewModel{
    
    self.msgView = [[MsgTableView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:self.msgView];
//    綁定數(shù)據(jù)
    RAC(self.msgView,dataList)  = RACObserve(self.viewModel, dataList);
    //執(zhí)行命令
    [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
//加載數(shù)據(jù)
@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{
    //加載數(shù)據(jù)
    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];//加載網(wǎng)絡(luò)請求的數(shù)據(jù)  對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()<UITableViewDataSource,UITableViewDelegate>

@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 = @"說明:已通過審核的模板可能會根據(jù)當(dāng)前政策變化被禁用";
        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]];///按鈕綁定方法  并將當(dāng)前控制器傳入到viewModel方法中
        }];
        btn;
    }));
}
//獲取當(dāng)前控制器
-(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 前言 由于最近兩個多月,筆者正和小伙伴們忙于對公司新項目的開發(fā),筆者主要負(fù)責(zé)項目整體架構(gòu)的搭建以及功能模塊的分工。...
    CoderMikeHe閱讀 27,155評論 74 270
  • 非習(xí)慣于莊重 寂靜無光 窗簾裝飾出安撫 光環(huán)喧囂 轉(zhuǎn)側(cè)地球背面 子夜輾轉(zhuǎn)的身體 不做抽出鋼筋的水泥 脊骨挺括堅守 ...
    涼爽清風(fēng)閱讀 498評論 1 8
  • 可是,我們也真的應(yīng)該相信,在世界的某個角落,或許也有那么一個人,跟你一樣的經(jīng)歷社會的浮沉與變更。一樣的為了生活而奮...
    往生飛魚閱讀 271評論 0 0
  • 竿頭百尺并日連,乘車擁偃溫地炎。 九天玄女借風(fēng)向,別處逢心一處閑。 拈草衰翁放游鳶,握轅轉(zhuǎn)柄自糾纏。 長云飄線紛飛...
    d03e056874dc閱讀 346評論 0 0
  • 天氣已經(jīng)逐漸轉(zhuǎn)冷,她和他相繼走出會場。天空早已昏暗了,灰白的月光終于費勁的鉆出薄霧,把它那寒冷的光線投射到這個巨大...
    小花Ivan閱讀 283評論 0 0