MVVM在iOS中的使用

1.理解:

MVVM是一種設計模式,本質在于ViewModel與View或Controller層進行綁定,model層數據變化可以通過ViewModel直接更新UI。

開發過程中,從可讀性和開發效率上簡單的視圖傾向于Controller持有特定的ViewModel。

2.優勢

(1)簡化開發

一個Controller針對某一任務持有其ViewModel,而非View或者subView持有,只需要維護Controller這一層的ViewModel;

(2)解耦

讓View專注于視圖和視圖邏輯,ViewModel專注于邏輯處理、網絡請求、數據解析以及暴露數據接口;

(3)便于測試,高復用性

View和ViewModel由于低耦合性,可以方便被其它模塊調用。ViewModel可以單獨調試。

3.使用場景

場景:博文列表

屬性 類型
authorLabel作者 UILabel
avatarImgView頭像 UIImageView
contentLabel博文 UILabel

Cell層,提供外部訪問的組件

@interface BlogCell : TYBaseTableViewCell

/// 作者
@property (nonatomic, strong) UILabel *authorLabel;

/// 頭像
@property (nonatomic, strong) UIImageView *avatarImgView;

/// 博文
@property (nonatomic, strong) UILabel *contentLabel;

@end

ViewModel層,提供數據源,提供方式給C層Subscribe,從而刷新數據,以下提供3種方式狀態值,RACSubject,RACCommand

@interface BlogViewModel : NSObject

/// 數據源
@property (nonatomic, strong) NSMutableArray *dataArray;

/// 狀態:刷新狀態
@property (nonatomic, assign) TYStatus status;

/// 單向
@property (nonatomic, strong) RACSubject *subject;

/// 雙向
@property (nonatomic, strong) RACCommand *command;

@end

Controller層,視圖的配置和初始化等,主要有3塊:1、cell的賦值 2、UI邏輯下拉刷新 3、UI邏輯加載更多

    // Cell的配置和賦值
    [listView setConfigCellBlock:^UITableViewCell * _Nonnull(UITableView * _Nonnull table, NSIndexPath * _Nonnull indexPath) {
        BlogCell *cell = [table dequeueReusableCellWithIdentifier:NSStringFromClass([BlogCell class])];
        if (indexPath.row < weakSelf.blogVM.dataArray.count) {
            id info = weakSelf.blogVM.dataArray[indexPath.row];
            cell.avatarImgView.image = [UIImage imageNamed:info[@"avatar"]];
            cell.authorLabel.text    = info[@"author"];
            cell.contentLabel.text   = info[@"content"];
        }
        return cell;
    }];
    // 刷新
    [listView setRefreshBlock:^{
        [weakSelf request];
    }];
    // 加載更多
    [listView setLoadMoreBlock:^{
        [weakSelf loadMore];
    }];

Controller層,綁定ViewModel和更新View,以下提供2種方式,RACSubject和自定義狀態

- (void)bind {
    @weakify(self);
    [self.blogVM.subject subscribeNext:^(id  _Nullable x) {
            // ....
    }];

    [RACObserve(self.blogVM, status)subscribeNext:^(id  _Nullable x) {
        @strongify(self);
        NSInteger val = [x integerValue];
        if (val == TYStatusRefreshCompleted) {
            [self.listView endRefresh];
            [self.listView reloadData];
        }
        else if (val == TYStatusLoadCompleted) {
            [self.listView endLoadingMore];
            [self.listView reloadData];
        }
    }];
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。