在上一篇博文,我们讲解了MVVM框架的相关知识。在这篇博文将使用ReactiveCocoa第三方库实现MVVM架构。
1 引入ReactiveCocoa库
使用CocoaPods引入第三分库ReactiveCocoa。Podfile内相关内容如下:
platform :ios,'9.0'
pod 'ReactiveCocoa','~> 2.3.1'
2 界面设计
YJViewController类代码如下。
//
// YJViewController.m
// MVVM-ReactiveCocoa
//
// CSDN:http://blog.csdn.net/y550918116j
// GitHub:https://github.com/937447974/Blog
//
// Created by admin on 16/3/7.
// Copyright © 2016年 阳君. All rights reserved.
//
#import "YJViewController.h"
#import <ReactiveCocoa/ReactiveCocoa.h>
#import "RACEXTScope.h"
#import "YJviewmodel.h"
@interface YJViewController ()
@property (weak,nonatomic) IBOutlet UITextField *userNameTextField; ///< 用户名
@property (weak,nonatomic) IBOutlet UITextField *passwordTextField; ///< 密码
@property (weak,nonatomic) IBOutlet UIButton *loginButton; ///< 登录按钮
@property (nonatomic,strong) YJviewmodel *viewmodel; ///< viewmodel对象
@end
@implementation YJViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
@end
3 MVVM实现
3.1 viewmodel
我们实现一个简单的viewmodel层。
YJviewmodel.h
//
// YJviewmodel.h
// MVVM-ReactiveCocoa
//
// CSDN:http://blog.csdn.net/y550918116j
// GitHub:https://github.com/937447974/Blog
//
// Created by admin on 16/3/7.
// Copyright © 2016年 阳君. All rights reserved.
//
#import <Foundation/Foundation.h>
/** viewmodel完全把Model和View进行了分离,主要的程序逻辑在viewmodel里实现*/
@interface YJviewmodel : NSObject
@property (nonatomic,copy) NSString *userName; ///< 用户名
@property (nonatomic,copy) NSString *password; ///< 密码
@property (nonatomic,copy) NSString *title; ///< 标题
/** * 初始化相关数据 * * @return void */
- (void)initData;
@end
YJviewmodel.m
//
// YJviewmodel.m
// MVVM-ReactiveCocoa
//
// CSDN:http://blog.csdn.net/y550918116j
// GitHub:https://github.com/937447974/Blog
//
// Created by admin on 16/3/7.
// Copyright © 2016年 阳君. All rights reserved.
//
#import "YJviewmodel.h"
@implementation YJviewmodel
- (void)initData
{
NSLog(@"用户名:%@; 密码:%@",self.userName,self.password);
self.title = @"阳君:937447974";
}
@end
3.2 引入ReactiveCocoa实现MVVM
下面改造YJViewController.m完成和viewmodel层的绑定。
这里实现的需求如下:
- 时刻监听用户的输入,当用户输入的用户名和密码大于三位时才能点击登录按钮。
- 用户输入错误时输入框显示红色,正确时显示绿色。
- 用户输入错误登录按钮不可点,输入正确登录按钮可点。
- 用户点击登录按钮1s内重复点击无效。
核心代码实现如下:
- (void)viewDidLoad {
[super viewDidLoad];
// 校验用户输入信息
RACSignal *validUserNameSignal = [self.userNameTextField.rac_textSignal map:^id(NSString *value) {
return @(value.length > 3);
}];
RACSignal *validPasswordSignal = [self.passwordTextField.rac_textSignal map:^id(NSString *value) {
return @(value.length > 3);
}];
// 根据用户输入信息修改输入框背景色
RAC(self.userNameTextField,backgroundColor) = [validUserNameSignal map:^id(NSNumber *value) {
return value.boolValue ? [UIColor greenColor] : [UIColor redColor];
}];
RAC(self.passwordTextField,backgroundColor) = [validPasswordSignal map:^id(NSNumber *value) {
return value.boolValue ? [UIColor greenColor] : [UIColor redColor];
}];
// 按钮能否点击
RAC(self.loginButton,enabled) = [RACSignal combineLatest:@[validUserNameSignal,validPasswordSignal] reduce:^id(NSNumber *usernameValid,NSNumber *passwordValid){
return @([usernameValid boolValue] && [passwordValid boolValue]);
}];
@weakify(self);
// 1s内禁止重复点击
[[[[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside] map:^id(id value) {
@strongify(self);
self.loginButton.enabled = NO;
[self.viewmodel initData];
return @(true);
}] throttle:1] subscribeNext:^(id x) {
@strongify(self);
self.loginButton.enabled = YES;
}];
// viewmodel绑定
self.viewmodel = [[YJviewmodel alloc] init];
RAC(self.viewmodel,userName) = [self.userNameTextField.rac_textSignal map:^id(id value) {
return value;
}];
RAC(self.viewmodel,password) = [self.passwordTextField.rac_textSignal map:^id(id value) {
return value;
}];
RAC(self,title) = RACObserve(self.viewmodel,title);
}
点击运行即可看见相应效果。
Appendix
Sample Code
Revision History
时间 | 描述 |
---|---|
2016-03-08 | 博文完成 |