美文网首页iOS专题
iOS 基于 MVVM 编程实践(附上简单的demo)

iOS 基于 MVVM 编程实践(附上简单的demo)

作者: Jniying | 来源:发表于2019-01-14 17:25 被阅读6次

    关于 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:有更好的建议和意见欢迎留言,共同学习进步)

    相关文章

      网友评论

        本文标题:iOS 基于 MVVM 编程实践(附上简单的demo)

        本文链接:https://www.haomeiwen.com/subject/zxxjdqtx.html