MVVM模式将Presenter改名为ViewModel,基本上与MVP模式完全一致。
唯一的区别是,它采用双向绑定(data-binding) : View<->ViewModel, ViewModel作为Model中值的映射,是数据发生改变时,通知View中发生改变,以后不需要考虑View和Model之间的交互更新,只需着手界面布局逻辑即可。
①View和Model 不直接关联,而是通过ViewModel作为枢纽,沟通View和Model之间的关系。
②View中控件的值与属性进行绑定,通过KVO键值观察(这样当model的值发生变化时,View会自动发生改变)
View和Model通过ViewModel实现动态关联。
1.MVVModel代码
#import <Foundation/Foundation.h> @interface MVVMModel : NSObject @property(nonatomic,copy)NSString *name; @end
2.MVVMViewModel代码
MVVMViewModel.h
#import <Foundation/Foundation.h> #import "MVVMModel.h" @interface MVVMViewModel : NSObject @property(nonatomic,copy)NSString *nameStr; @property(nonatomic,strong)MVVMModel *model; -(void)setWithModel:(MVVMModel *)model; -(void)clickChangeName; @end
MVVMViewModel.m
#import "MVVMViewModel.h" @implementation MVVMViewModel -(instancetype)init{ if (self = [super init]) { } return self; } -(void)setWithModel:(MVVMModel *)model{ self.model = model; self.nameStr = model.name; } -(void)clickChangeName{ self.model.name = [NSString stringWithFormat:@"name%d",arc4random()%10]; self.nameStr = self.model.name; NSLog(@"%@",self.nameStr); } @end
3.MVVMView代码
#import <UIKit/UIKit.h> #import "MVVMViewModel.h" @interface MVVMView : UIView -(void)setWithViewModel:(MVVMViewModel *)vm; @end #import "MVVMView.h" @interface MVVMView () @property(nonatomic,strong)MVVMViewModel *vm; @property(nonatomic,strong)UILabel *label; @property(nonatomic,strong)UIButton *button; @end @implementation MVVMView - (instancetype)init { self = [super init]; if (self) { self.backgroundColor = [UIColor whiteColor]; self.frame = [UIScreen mainScreen].bounds; self.label = [[UILabel alloc]initWithFrame:CGRectMake(150,100 , 100, 30)]; self.label.backgroundColor = [UIColor orangeColor]; [self addSubview:_label]; self.button = [UIButton new]; _button.backgroundColor = [UIColor redColor]; [_button setTitle:@"点击" forState:UIControlStateNormal]; [_button addTarget:self action:@selector(mvvmClickChangModel) forControlEvents:UIControlEventTouchUpInside]; _button.frame = CGRectMake(150, 200, 50, 50); [self addSubview:_button]; } return self; } - (void)setWithViewModel:(MVVMViewModel *)vm { self.vm = vm; //KVO [self.vm addObserver:self forKeyPath:@"nameStr" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil]; self.label.text = vm.nameStr; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change: (NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"nameStr"]&&[change objectForKey:NSKeyValueChangeNewKey]) { NSNumber *new = [change objectForKey:NSKeyValueChangeNewKey]; self.label.text = [NSString stringWithFormat:@"%@",new]; } } -(void)mvvmClickChangModel{ [self.vm clickChangeName]; } -(void)dealloc{ [self.vm removeObserver:self forKeyPath:@"nameStr"]; } @end
3.ViewController.m
#import "ViewController.h" #import "MVVMView.h" #import "MVVMModel.h" #import "MVVMViewModel.h" @interface ViewController () @property (nonatomic, strong) MVVMViewModel * viewModel ; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; MVVMView *MView = [MVVMView new]; MVVMModel *model = [MVVMModel new]; model.name = @"name1"; MVVMViewModel *viewModel = [MVVMViewModel new]; [self.view addSubview:MView]; //*viewModel 作为枢纽 沟通view和model之间关系 [viewModel setWithModel:model]; [MView setWithViewModel:viewModel]; } @end