Contents 非表示
実装
Storyboard
LoginViewModel.swift (ロジック)
import RxSwift
import RxCocoa
protocol LoginViewModelInputs {
var id: PublishRelay<String> { get }
var password: PublishRelay<String> { get }
}
protocol LoginViewModelOutputs {
var isLoginButtonEnabled: Driver<Bool> { get }
}
protocol LoginViewModelType {
var inputs: LoginViewModelInputs { get }
var outputs: LoginViewModelOutputs { get }
}
class LoginViewModel: LoginViewModelType, LoginViewModelInputs, LoginViewModelOutputs {
// MARK: - Input Sources
let id = PublishRelay<String>()
let password = PublishRelay<String>()
// MARK: - Output Sources
let isLoginButtonEnabled: Driver<Bool>
// MARK: - Properties
var inputs: LoginViewModelInputs { return self }
var outputs: LoginViewModelOutputs { return self }
private let _isLoginButtonEnabled = BehaviorRelay<Bool>(value: false)
private let disposeBag = DisposeBag()
init() {
self.isLoginButtonEnabled = _isLoginButtonEnabled.asDriver(onErrorJustReturn: false)
Observable.combineLatest(id, password)
.map { !$0.0.isEmpty && !$0.1.isEmpty }
.bind(to: _isLoginButtonEnabled)
.disposed(by: disposeBag)
}
}
HomeViewController.swift (メインのView)
import UIKit
import RxSwift
import RxCocoa
final class HomeViewController: UIViewController {
// MARK: - Properties
@IBOutlet private weak var idTextField: UITextField!
@IBOutlet private weak var passwordTextField: UITextField!
@IBOutlet private weak var loginButton: UIButton!
private let viewModel: LoginViewModelType = LoginViewModel()
private let disposeBag = DisposeBag()
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
bind()
}
}
// MARK: - Bindings
private extension HomeViewController {
func bind() {
idTextField.rx.text.orEmpty
.bind(to: viewModel.inputs.id)
.disposed(by: disposeBag)
passwordTextField.rx.text.orEmpty
.bind(to: viewModel.inputs.password)
.disposed(by: disposeBag)
viewModel.outputs.isLoginButtonEnabled
.drive { [weak self] isButtonEnabled in
self?.loginButton.backgroundColor = isButtonEnabled ? UIColor.systemIndigo : UIColor.lightGray
}
.disposed(by: disposeBag)
}
}