iOS手把手教你实现一个规范的MVVM

2019-10-24  本文已影响0人  王方帅

Model:

1,先上代码:
DDDUSBaoIntroduceModel.h
@interface DDDUSBaoIntroduceModel : NSObject

@property (nonatomic,copy) NSString *top_info;
@property (nonatomic,copy) NSString *top_txt;
@property (nonatomic,copy) NSString *introduction;
@property (nonatomic,copy) NSString *introduction_info;
@property (nonatomic,copy) NSString *rate_txt;
@property (nonatomic,copy) NSArray  *rate_info;
@property (nonatomic,copy) NSString *rule_url;
@property (nonatomic,copy) NSString *footer_txt;
@property (nonatomic,copy) NSString *footer_introduction;

@end

@interface DDDUSBaoKeyValueModel : NSObject

@property (nonatomic,copy) NSString *title;
@property (nonatomic,copy) NSString *value;

@end

DDDUSBaoIntroduceModel.m
@implementation DDDUSBaoIntroduceModel

+ (NSDictionary *)modelContainerPropertyGenericClass {
    // value should be Class or Class name.
    return @{@"rate_info" : [DDDUSBaoKeyValueModel class]};
}

@end

@implementation DDDUSBaoKeyValueModel
@synthesize value = _value;

- (NSString *)value {
    return StrValid(_value)?_value:@"";
}

@end
2,可包含的内容
3,不可包含的内容

View:

1,先上代码
.h中
@interface USBaoKLineView : UIView

@property (nonatomic,copy) NSString  *title;
@property (nonatomic,strong) DDDUSBaoBuyViewModel   *buyViewModel;

@end

.m中
@interface USBaoKLineView ()<IChartAxisValueFormatter,ChartViewDelegate>

@property (nonatomic, strong) LineChartView *chartView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic,copy) NSArray  <DDDUSBaoKeyValueModel *>*rate_info;

@end

@implementation USBaoKLineView
//子View的创建
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.backgroundColor = DDDLightBlackColor;
        
        [self createChartView];
        
        _titleLabel = [UILabel sr_labelWithFrame:CGRectZero title:self.title font:BoldFont_DDD(15) textAlignment:NSTextAlignmentCenter titleColor:DDDWhiteColor];
        [self addSubview:_titleLabel];
        [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(10);
            make.left.mas_equalTo(100);
            make.right.mas_equalTo(-100);
            make.height.mas_equalTo(30);
        }];
    }
    return self;
}
//传入ViewModel的接口
- (void)setBuyViewModel:(DDDUSBaoBuyViewModel *)buyViewModel {
    if (_buyViewModel != buyViewModel) {
        _buyViewModel = buyViewModel;
        _rate_info = buyViewModel.rate_info;
        [self updateChartData];
    }
}
@end
1,包含的内容

ViewModel:

1,先上代码
@interface DDDUSBaoBuyViewModel : NSObject

@property (nonatomic,strong) DDDUSBaoIntroduceModel *model;
@property (nonatomic,copy) NSArray  <DDDUSBaoKeyValueModel *>*rate_info;

- (void)fundDetailWithSuccess:(DDDRequestModelSucccessBlock)success
                      failure:(DDDRequestModelFailureBlock)failure;

@end
@implementation DDDUSBaoBuyViewModel
- (void)fundDetailWithSuccess:(DDDRequestModelSucccessBlock)success
                      failure:(DDDRequestModelFailureBlock)failure {
    NSString *URLString = [NSString stringWithFormat:@"%@%@",
                           kRadarbrokersURL,
                           @"/appapi/fund/funddetail"];
    
    NSDictionary *parameters = @{};
    [DDDRequestManager POST:URLString parameters:parameters success:^(NSDictionary *responseDict) {
        if ([responseDict[@"code"] integerValue] == 0) {
            
            DDDUSBaoIntroduceModel *introduceModel = [DDDUSBaoIntroduceModel yy_modelWithJSON:responseDict[@"data"]];
            self.model = introduceModel;
            self.rate_info = introduceModel.rate_info;
            if (success) {
                success(self);
            }
        } else {
            NSError *error = [NSError errorWithDomain:responseDict[@"msg"] code:[responseDict[@"code"] integerValue] userInfo:nil];
            if (error) {
                failure(error);
            }
        }
        
    } failure:^(NSError *error) {
        if (error) {
            failure(error);
        }
    }];
}
@end
2,包含的内容
2,注意

一个VC中可包含多个Model,多个ViewModel,多个自定义View,VC负责某个View和ViewModel的绑定,View从ViewModel中取出对应的数据填充View

ViewController:

1,先上代码
//View的创建,布局
- (void)createUI {
    [self.view addSubview:self.mainScrollView];
    self.mainScrollView.backgroundColor = Radar_Page_Bg_Color;
    WeakSelf(weakSelf)
    [self.mainScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.mas_equalTo(0);
        make.width.mas_equalTo(SCREEN_WIDTH);
        make.height.equalTo(weakSelf.view.mas_height).offset(-44-32-kIPhone_Bottom_SafeArea_Height);
    }];
    
    UIView *headerView = [[UIView alloc] init];
    [self.mainScrollView addSubview:headerView];
    CGFloat imageHeight = SCREEN_WIDTH*(135/375.0);
    [headerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.mas_equalTo(0);
        make.width.mas_equalTo(SCREEN_WIDTH);
        make.height.mas_equalTo(imageHeight+44);
    }];

    [headerView addSubview:self.annualizedLabel];
    [self.annualizedLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.mas_equalTo(200);
        make.centerX.mas_equalTo(0);
        make.height.mas_equalTo(36);
        make.centerY.equalTo(headerImageView.mas_centerY).offset(-15);
    }];
}

#pragma mark -GetMethods
- (UIScrollView *)mainScrollView {
    if (!_mainScrollView) {
        _mainScrollView = [[UIScrollView alloc] init];
    }
    return _mainScrollView;
}

- (UILabel *)annualizedLabel {
    if (!_annualizedLabel) {//2.27%
        _annualizedLabel = [UILabel sr_labelWithFrame:CGRectZero title:@"" font:BoldFont_DDD(36) textAlignment:(NSTextAlignmentCenter) titleColor:[UIColor whiteColor]];
    }
    return _annualizedLabel;
}

- (DDDUSBaoBuyViewModel *)buyViewModel {
    if (!_buyViewModel) {
        _buyViewModel = [[DDDUSBaoBuyViewModel alloc] init];
    }
    return _buyViewModel;
}

//ViewModel的创建
    WeakSelf(weakSelf);
    [RadarHUD showLoading];
    [self.buyViewModel fundDetailWithSuccess:^(id obj) {
        [RadarHUD dismiss];
        [weakSelf reloadData];
    } failure:^(NSError *error) {
        [RadarHUD dismiss];
        [RadarToast showToastWithMessage:error.domain CompletionBlock:^{
            [weakSelf goback:nil];
        }];
    }];
//数据绑定
- (void)reloadData {
    DDDUSBaoIntroduceModel *model = _buyViewModel.model;
    _annualizedLabel.text = model.top_info;
    _annualizedPromptLabel.text = model.top_txt;
    _barLabel.text = model.introduction;
    [_introduceLabel sr_setText:model.introduction_info lineSpacing:10 withLimitWidth:SCREEN_WIDTH-17*2];
    _klineView.rate_info = model.rate_info;
    _klineView.title = model.rate_txt;
    [_flexibleAccessLabel sr_setText:model.footer_txt lineSpacing:10 withLimitWidth:SCREEN_WIDTH-17*2];
    [_tAdd0SurplusLabel sr_setText:model.footer_introduction lineSpacing:0 withLimitWidth:SCREEN_WIDTH-17*2];
}
2,包含的内容

小结

根据Casa博客中说的总结了以下关键内容:

参考文献及Demo:

https://github.com/ibireme/YYModel
https://github.com/coderyi/MVVMDemo
https://casatwy.com/iosying-yong-jia-gou-tan-viewceng-de-zu-zhi-he-diao-yong-fang-an.html

上一篇 下一篇

猜你喜欢

热点阅读