【RxSwift】UITextFieldとUILabelのデータバインディング
はじめに
- RxSwiftの導入を検討している。
- Swiftで書いてきたけれど、RxSwiftもこれから使っていきたい。
と言ったRxSwift初心者向けの記事です。
RxSwiftを使って簡単なデータバインディングのサンプルを作成します。
この記事のゴール
この記事では、ViewControllerとViewModelの値をbindさせて、UITextFieldが更新されたら、UILabelが更新されるサンプルを作成します。
サンプルの全体像
ViewControllerとViewModel間でデータバインディングを行なって、値が更新されたらViewが更新します。
下準備
Xcodeで新規プロジェクトを作成して、RxSwiftとRxCocoaをインポートします。
RxSwiftとRxCocoaをインポートする
こちらの記事を参考にRxSwiftをプロジェクトにインポートしてください。
Viewの準備
まずStoryBoardにUITextFieldとUILabelを置いて、ViewControllerに紐付けます。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak private var textField: UITextField!
@IBOutlet weak private var titleLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}
TextFieldの更新を監視
続いてTextFieldが入力を監視するコードをViewControllerに追加します。
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak private var textField: UITextField!
@IBOutlet weak private var titleLabel: UILabel!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
bind()
}
private func bind() {
textField.rx.text.orEmpty.asObservable()
.subscribe { [weak self] in
// ここでViewModelに値の更新を通知します。
}
.disposed(by: disposeBag)
}
}
ViewModelで対象の値の作成
ViewModel.swift
import RxSwift
class ViewModel {
var title: Observable<String> {
return titleSubject
}
private let titleSubject = PublishSubject<String>()
}
import RxSwift
class ViewModel {
var title: Observable<String> {
return titleSubject
}
private let titleSubject = PublishSubject<String>()
}
監視対象の変数を作成して、管理をします。
対象となるtitleSubjectは、外から更新できないようにカプセル化します。
ViewControllerで値を受け取るコードを追加
ViewContoller.swift
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak private var textField: UITextField!
@IBOutlet weak private var titleLabel: UILabel!
private let viewModel = ViewModel()
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
bind()
}
private func bind() {
textField.rx.text.orEmpty.asObservable()
.subscribe { [weak self] in
// ここでViewModelに値の更新を通知します。
}
.disposed(by: disposeBag)
viewModel.title.asObservable()
.subscribe { [weak self] in
// ここでViewModelの更新を受け取ります。
}.disposed(by: disposeBag)
}
}
ViewControllerからVideModelの値を更新する
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak private var textField: UITextField!
@IBOutlet weak private var titleLabel: UILabel!
private let viewModel = ViewModel()
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
bind()
}
private func bind() {
textField.rx.text.orEmpty.asObservable()
.subscribe { [weak self] in
// ここでViewModelに値の更新を通知します。
}
.disposed(by: disposeBag)
viewModel.title.asObservable()
.subscribe { [weak self] in
// ここでViewModelの更新を受け取ります。
}.disposed(by: disposeBag)
}
}
ViewModelの管理対象はカプセル化していますので、新しく関数を作って値の更新を行います。
private func bind() {
textField.rx.text.orEmpty.asObservable()
.subscribe { [weak self] in
guard let value = $0.element else { return }
self?.viewModel.set(text: value)
}
.disposed(by: disposeBag)
viewModel.title.asObservable()
.subscribe { [weak self] in
// ここでViewModelの更新を受け取ります。
}.disposed(by: disposeBag)
}
import RxSwift
class ViewModel {
var title: Observable<String> {
return titleSubject
}
private let titleSubject = PublishSubject<String>()
func set(text: String) {
titleSubject.onNext(text)
}
}
これでViewControllerからVideModelの監視された値を更新することができました。
ViewModelの更新を受け取ってViewを更新する
ViewModelの更新をすることができました。
最後に先ほど作成したViewModelの値の更新を受け取るコードの中に、Viewを更新するコードを追加します。
private func bind() {
textField.rx.text.orEmpty.asObservable()
.subscribe { [weak self] in
guard let value = $0.element else { return }
self?.viewModel.set(text: value)
}
.disposed(by: disposeBag)
viewModel.title.asObservable()
.subscribe { [weak self] in
self?.titleLabel.text = $0.element
}.disposed(by: disposeBag)
}
簡単にUITextFieldとUILabelのデータをバインディングすることができました。
サンプルコード
https://github.com/hananao/RxSwift_Begin_Sample_UITextField_UILabel
まとめ
細かい部分の説明は不十分ですが、簡単にRxSwiftを使ってデータバインディングすることができました。
記事について間違っている部分やご指摘などありましたら、コメントにお願いします。
Author And Source
この問題について(【RxSwift】UITextFieldとUILabelのデータバインディング), 我々は、より多くの情報をここで見つけました https://qiita.com/hananaonao/items/c0083cecbbadf41f9337著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .