关于 MVVM 和 MVC 的详解 以及优缺点可以移步到参考链接,这里不再做多解释了。写这篇文章主要是想表达MVVM一个简单的实现(有很多大神也发了很多demo 过于复杂)。
MVVM 实践
MVVM_demo.png上面是这个 demo 的文件结构
View文件:自定义的view
Model文件: 数据
ViewModel文件:业务逻辑,网络请求,数据缓存,UI状态,但不包括任何UIKit的类
ViewController文件:只负责 UI更新,UI跳转业务
MVVM.png
根据 MVVM 通讯思想
屏幕快照 2019-01-14 下午4.52.27.png
所有的 业务逻辑,网络请求,数据缓存,UI的状态 都包括在 ViewModel 里面。
@interface JNViewModel : JNBaseViewModel
@property (nonatomic, assign) BOOL refreshBtnEnabled;/**<更新按钮是否可以点击 默认为Yes*/
@property (nonatomic, assign) BOOL refreshBtnHidden;/**<更新按钮是否显示 默认为NO*/
@property (nonatomic, assign) BOOL tableViewHidden;/**<列表是否展示 默认为YES*/
@property (nonatomic, strong) NSMutableArray *datas;/**<数据*/
//点击按钮加载数据
- (void)refreshBtnAction;
- (void)didSelectAction:(NSInteger)row;
@end
ViewModel.m 把 业务逻辑,网络请求,数据缓存 从 MVC 中的 Controller 拆分出来
//设置初始状态
- (instancetype)init{
self = [super init];
if (self) {
_refreshBtnHidden = NO;
_tableViewHidden = YES;
_refreshBtnEnabled = YES;
_datas = [NSMutableArray new];
}
return self;
}
//响应事件更新数据逻辑处理
- (void)refreshBtnAction {
//请求数据前更新UI
self.refreshBtnEnabled = NO;
if ([self.updateUIDelegate respondsToSelector:@selector(updateUI)]){
[self.updateUIDelegate updateUI];
}
//网络请求,数据缓存
[[NSOperationQueue new] addOperationWithBlock:^{
sleep(3);
[self.datas removeAllObjects];
for (int i = 0; i<30; i++) {
JNModel *model = [[JNModel alloc] init];
model.name = [NSString stringWithFormat:@"test%d",i];
model.idNumber = [NSString stringWithFormat:@"atTest%d",i];
[self.datas addObject:model];
}
//请求数据后更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.refreshBtnEnabled = YES;
self.refreshBtnHidden = YES;
self.tableViewHidden = NO;
if ([self.updateUIDelegate respondsToSelector:@selector(updateUI)]){
[self.updateUIDelegate updateUI];
}
}];
}];
}
//cell点击数据业务处理
- (void)didSelectAction:(NSInteger)row {
JNModel *model = self.datas[row];
if ([self.updateUIDelegate respondsToSelector:@selector(didSelectAction:)]){
[self.updateUIDelegate didSelectAction:model.name];
}
}
在 ViewModel 的基类 BaseViewModel 设置 更新UI的代理 以及 点击事件触发是需要更新UI的代理
@protocol JNViewModelUpdateUIDelegate <NSObject>
//更新UI的代理
- (void)updateUI;
//响应代理
- (void)didSelectAction:(id)object;
@end
@interface JNBaseViewModel : NSObject
@property (nonatomic, weak) id <JNViewModelUpdateUIDelegate> updateUIDelegate;/**<更新UI的代理*/
@end
ViewController 只负责UI相关的逻辑
#pragma mark --JNViewModelUpdateUIDelegate
//更新ui
- (void)updateUI {
self.tableView.hidden = self.viewModel.tableViewHidden;
self.refreshBtn.hidden = self.viewModel.refreshBtnHidden;
self.refreshBtn.enabled = self.viewModel.refreshBtnEnabled;
if (!self.tableView.hidden) {
[self.tableView reloadData];
}
}
//ui业务处理
- (void)didSelectAction:(id)object {
UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:object message:@"详细的说明" preferredStyle:UIAlertControllerStyleAlert];
[alertVc addAction:[UIAlertAction actionWithTitle:@"关闭" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
[self presentViewController:alertVc animated:YES completion:nil];
}
demo链接
https://github.com/Jniying/single_MVVM_Demo
参考链接
https://www.jianshu.com/p/caaa173071f3
https://www.jianshu.com/p/f1d0f7f01130
https://casatwy.com/iosying-yong-jia-gou-tan-wang-luo-ceng-she-ji-fang-an.html
(ps:有更好的建议和意见欢迎留言,共同学习进步)
网友评论