UITextField Binds to ViewModel with RxSwift

I am ready to use RxSwift to bind MVVM between model values ​​and view controllers. I wanted to follow this tutorial on realm.io , but since then the binding has apparently changed and the sample code does not compile. Here is a sample code where I think I fixed the worst typos / missed things:

LoginViewModel.swift

import RxSwift

struct LoginViewModel {

    var username = Variable<String>("")
    var password = Variable<String>("")

    var isValid : Observable<Bool>{
        return Observable.combineLatest(self.username.asObservable(), self.password.asObservable())
        { (username, password) in
            return username.characters.count > 0
                && password.characters.count > 0
        }
    }
} 

LoginViewController.swift

import RxSwift
import RxCocoa
import UIKit

class LoginViewController: UIViewController {
    var usernameTextField: UITextField!
    var passwordTextField: UITextField!
    var confirmButton: UIButton!

    var viewModel = LoginViewModel()

    var disposeBag = DisposeBag()

    override func viewDidLoad() {
        usernameTextField.rx.text.bindTo(viewModel.username).addTo(disposeBag)
        passwordTextField.rx.text.bindTo(viewModel.password).addTo(disposeBag)

        //from the viewModel
        viewModel.rx.isValid.map { $0 }
            .bindTo(confirmButton.rx.isEnabled)
    }
}

Controller bindings do not compile. The right way to do this is almost impossible, since the RxSwift documentation is pretty useless, and Xcode auto-completion doesn't offer anything useful.

The first problem usernameTextField.rx.text.bindTo(viewModel.username).addTo(disposeBag)with this binding, which does not compile:usernameTextField.rx.text.bindTo(viewModel.username).addTo(disposeBag)

Mistake:

LoginViewController.swift:15:35: Cannot invoke 'bindTo' with an argument list of type '(Variable<String>)'

I tried the following without luck:

1) usernameTextField.rx.text.bind(to: viewModel.username).addTo(disposeBag) - : LoginViewController.swift:15:35: Cannot invoke 'bind' with an argument list of type '(to: Variable<String>)'

2) let _ = viewModel.username.asObservable(). Bind (to: passwordTextField.rx.text)

let _ = viewModel.username.asObservable()
            .map { $0 }
            .bind(to: usernameTextField.rx.text)

, (.. viewModel.username )

, bind bind(to: , ... swift 3 Xcode 8.3.2.

+15
2

@XFreire , orEmpty , orEmpty , , , :

...

  • Variable let. - , .
  • isValid, , / . , , . isValid .

Rx , let . .

struct LoginViewModel {

    let username = Variable<String>("")
    let password = Variable<String>("")

    let isValid: Observable<Bool>

    init() {
        isValid = Observable.combineLatest(self.username.asObservable(), self.password.asObservable())
        { (username, password) in
            return username.characters.count > 0
                && password.characters.count > 0
        }
    }
}

. , let Rx.

  • addDisposableTo() - disposed(by:)
  • bindTo() - bind(to:)
  • map viewModel.isValid.
  • disposed(by:) .

, viewModel var, - , .

class LoginViewController: UIViewController {
    var usernameTextField: UITextField!
    var passwordTextField: UITextField!
    var confirmButton: UIButton!

    let viewModel = LoginViewModel()
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        usernameTextField.rx.text
            .orEmpty
            .bind(to: viewModel.username)
            .disposed(by: disposeBag)

        passwordTextField.rx.text
            .orEmpty
            .bind(to: viewModel.password)
            .disposed(by: disposeBag)

        //from the viewModel
        viewModel.isValid
            .bind(to: confirmButton.rx.isEnabled)
            .disposed(by: disposeBag)
    }
}

, :

func confirmButtonValid(username: Observable<String>, password: Observable<String>) -> Observable<Bool> {
    return Observable.combineLatest(username, password)
    { (username, password) in
        return username.characters.count > 0
            && password.characters.count > 0
    }
}

viewDidLoad :

override func viewDidLoad() {
    super.viewDidLoad()

    let username = usernameTextField.rx.text.orEmpty.asObservable()
    let password = passwordTextField.rx.text.orEmpty.asObservable()

    confirmButtonValid(username: username, password: password)
        .bind(to: confirmButton.rx.isEnabled)
        .disposed(by: disposeBag)
}

, , . , , , .

+52

.orEmpty.

:

usernameTextField.rx.text
    .orEmpty
    .bindTo(self.viewModel. username)
    .addDisposableTo(disposeBag)

... UITextField s

text String?. orEmpty, String? String.

+15

All Articles