Using RxSwift, how to enable UIButton based on valid text?

In RxSwift / RxCocoa 2.0.0-beta 3, I have a ViewModel with:

let someString = Variable("")

func isValidSomeString() -> Observable<Bool>  {

    if someString.value.characters.count == 0 {
        return just(false)
    }
    return just(true)
}   

I have someString binding already to the text field in the ViewController.

Whenever someString changes (or perhaps a text box if this is the best way), I want the button to be enabled based on if someString.

I tried using the "Observable <Bool>", but started to go down a different path. I could do it in the ViewController:

    someViewModel.someString.subscribeNext { text -> Void in

        // could just someUIButton.enabled = someViewModel.isValidSomeString(text)

    }.addDisposableTo(disposeBag)

Is there no other way that is less verbose than the isValidSomeString (text) method? We already had good success with isValidLogin, which returns the Observable <Bool> that used combLatest.

+4
2

, Action - . Action ViewModel, enabledIf UIButton. , .

ViewModel :

var buttonAction: CocoaAction {
    let hasString = self.someString.map { !$0.isEmpty }
    return CocoaAction(enabledIf: hasString) {
        // do something when button tapped
        return empty()
    }
}

ViewController ViewModel :

myButton.rx_action = viewModel.buttonAction
+7

, map someString Obserable<Bool>, rx_enabled UIButton - :

someViewModel.someString
             .asObservable()
             .map { (str) -> Bool in
                 return someViewModel.isValidSomeString(text)
             }
            .bindTo(someUIButton.rx_enabled)
            .addDisposableTo(disposeBag)  

, , Variable<Bool> viewmodel

struct ViewModel {
....
    canLogIn = Variable(false)
}

rx_enabled :

  let userNameValidation = loginTextField
     .rx_text
     .map({!$0.isEmpty})
     .shareReplay(1)

  let passwordValidation = passwordTextField
     .rx_text
     .map({!$0.isEmpty})
     .shareReplay(1)

  let loginEnabled = combineLatest(userNameValidation, passWordValidation) { (username, password) in
     return username && password
  }

  loginEnabled
     .bindTo(loginViewModel.canlogIn)
     .addDisposableTo(disposeBag)

  loginViewModel.canlogIn
         .bindTo(loginButton.rx_enabled)
         .addDisposableTo(disposeBag)
+4
source

Source: https://habr.com/ru/post/1617987/


All Articles