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

首先說明,代碼來自老司機(jī),_

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

pod 'ReactiveCocoa', '~> 2.5' #

對MVVM的介紹學(xué)習(xí)http://www.reibang.com/p/87ef6720a096 講的比較詳細(xì)
話不多說 直接上代碼
1.viewController中 代碼就剩這么點(diǎn)


#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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子焦读,更是在濱河造成了極大的恐慌胧华,老刑警劉巖浸锨,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砂心,死亡現(xiàn)場離奇詭異稚补,居然都是意外死亡柬泽,警方通過查閱死者的電腦和手機(jī)慎菲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锨并,“玉大人露该,你說我怎么就攤上這事〉谥螅” “怎么了解幼?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長包警。 經(jīng)常有香客問我精刷,道長陕凹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮炫七,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好痒芝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著牵素,像睡著了一般严衬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笆呆,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天请琳,我揣著相機(jī)與錄音,去河邊找鬼赠幕。 笑死俄精,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的榕堰。 我是一名探鬼主播竖慧,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逆屡!你這毒婦竟也來了圾旨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤魏蔗,失蹤者是張志新(化名)和其女友劉穎砍的,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體莺治,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡廓鞠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谣旁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片床佳。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖榄审,靈堂內(nèi)的尸體忽然破棺而出砌们,到底是詐尸還是另有隱情,我是刑警寧澤瘟判,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布怨绣,位于F島的核電站角溃,受9級特大地震影響拷获,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜减细,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一匆瓜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦驮吱、人聲如沸茧妒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桐筏。三九已至,卻和暖如春拇砰,著一層夾襖步出監(jiān)牢的瞬間梅忌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工除破, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牧氮,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓瑰枫,卻偏偏與公主長得像踱葛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子光坝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

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

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