Я готов использовать RxSwift для привязки MVVM между значениями модели и контроллерами представления. Я хотел следовать этому руководству по realm.io, но с тех пор привязка, видимо, изменилась, и пример кода не компилируется. Вот пример кода, где я думаю, что я исправил худшие опечатки/пропущенные вещи:
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)
}
}
Привязки контроллера не компилируются. Правильный способ сделать это практически невозможно, поскольку документация по RxSwift довольно бесполезна, а автозаполнение XCode не предлагает ничего полезного.
Первая проблема usernameTextField.rx.text.bindTo(viewModel.username).addTo(disposeBag)
с этой привязкой, которая не компилируется: usernameTextField.rx.text.bindTo(viewModel.username).addTo(disposeBag)
Ошибка:
LoginViewController.swift:15:35: Cannot invoke 'bindTo' with an argument list of type '(Variable<String>)'
Я попробовал следующее без удачи:
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.