iOS: 利用 DVDataBind 双向绑定 + MVVM 简单实现登录界面

1.Demo展示

Demo地址: https://github.com/shidavid/DVDataBind
如果对 DVDataBind 有兴趣请看:基于KVO的轻量级iOS双向数据绑定响应式编程框架

ps: iOS录屏录不了输入密码过程



iOS: 利用 DVDataBind 双向绑定 + MVVM 简单实现登录界面_第1张图片
image

2.代码如下

  • LoginViewController:View 和 ViewModel 的绑定

@interface LoginViewController ()

@property(nonatomic, strong) LoginView *loginView;
@property(nonatomic, strong) LoginViewModel *loginViewModel;

@end


@implementation LoginViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initViews];
    [self initViewModels];
    [self bindViewModel];
}

#pragma mark - <-- Init -->
- (void)initViews {
    self.loginView = (LoginView *)self.view;
    self.loginView.backgroundColor = [UIColor Blue];
}

- (void)initViewModels {
    self.loginViewModel = [[LoginViewModel alloc] init];
}

- (void)bindViewModel {
    __weak __typeof(self)weakSelf = self;
    
    // 这里 View 跟 ViewModel 双向绑定
    DVDataBind
    ._in_ui(self.loginView.userNameText, @"text", UIControlEventEditingChanged)
    ._out(self.loginViewModel, @"userName")
    ._filter(^BOOL(NSString *text) {
        //这里判断用户名是否符合规范、校验、限制等等操作,return YES 数据才能更新
        return [weakSelf.loginViewModel filterUserName:text];
    })
    ._out_key_any(@"login.userName.text", ^{
        weakSelf.loginView.btnLogin.enabled = [weakSelf.loginViewModel btnLoginEnable];
    });
    
    
    DVDataBind
    ._in_ui(self.loginView.passwordText, @"text", UIControlEventEditingChanged)
    ._out_cv(self.loginViewModel, @"password", ^(NSString *text){
        // textField.secureTextEntry = YES时, text为密文, 需要转换
        return [NSString stringWithUTF8String:text.UTF8String];
    })
    ._filter(^BOOL(NSString *text) {
        NSString *tempText = [NSString stringWithUTF8String:text.UTF8String];
        return [weakSelf.loginViewModel filterPassword:tempText];
    })
    ._out_key_any(@"login.passwordText.text", ^{
        weakSelf.loginView.btnLogin.enabled = [weakSelf.loginViewModel btnLoginEnable];
    });
    
    
    DVDataBind
    ._in_ui(self.loginView.btnLogin, @"highlighted", UIControlEventTouchUpInside)
    ._out_key_any(@"login.btnLogin.login", ^{
        [weakSelf.loginViewModel login];
    });
}

@end
  • LoginView :UI 的初始化、配置和布局
@interface LoginView : UIView

@property (weak, nonatomic) IBOutlet UITextField *userNameText;
@property (weak, nonatomic) IBOutlet UITextField *passwordText;
@property (weak, nonatomic) IBOutlet UIButton *btnLogin;

@end
  • LoginViewModel : ViewModel是关于View的Model, 这里是业务逻辑、网络请求等等
@interface LoginViewModel : NSObject

@property(nonatomic, copy) NSString *userName;
@property(nonatomic, copy) NSString *password;

- (BOOL)btnLoginEnable;
- (BOOL)filterUserName:(NSString *)userName;
- (BOOL)filterPassword:(NSString *)password;
- (void)login;

@end


@implementation LoginViewModel

- (BOOL)btnLoginEnable {
    return (self.userName && self.userName.length > 0
            && self.password && self.password.length > 0);
}

- (BOOL)filterUserName:(NSString *)userName {
    // 这里可加 userName判断处理,限制
    return userName.length <= 15;
}

- (BOOL)filterPassword:(NSString *)password {
    // 这里可加 password判断处理,限制
    return password.length <= 20;
}

- (void)login {
    // Model是关于服务器的数据模型, ViewModel是关于View的Model
    LoginModel *model = [[LoginModel alloc] init];
    model.userName = self.userName;
    model.password = self.password;
    
    // 这里post model 到服务器
    NSLog(@"登录成功, userName -> %@, password -> %@", model.userName, model.password);
}

@end
  • LoginModel:关于服务器的数据模型,有网络请求才存在
@interface LoginModel : NSObject

@property(nonatomic, copy) NSString *userName;
@property(nonatomic, copy) NSString *password;

@end

3.结语:

Demo地址: https://github.com/shidavid/DVDataBind

你可能感兴趣的:(iOS: 利用 DVDataBind 双向绑定 + MVVM 简单实现登录界面)