iOS: 利用 DVDataBind 雙向綁定 + MVVM 簡單實現登陸界面

1.Demo展現

Demo地址: github.com/shidavid/DV…
若是對 DVDataBind 有興趣請看:基於KVO的輕量級iOS雙向數據綁定響應式編程框架git

ps: iOS錄屏錄不了輸入密碼過程 github

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地址: github.com/shidavid/DV…編程

相關文章
相關標籤/搜索