RxSwift의 Examples에 가만히 들어있는 양방향 데이터 바인딩의 연산자가 멋졌다

안녕하세요!

RxSwift (RxCocoa)를 사용해 모델←→뷰의 서로의 갱신을 전하는 양방향 데이터 바인딩을 해 봅니다.

SwiftBond 에서는 양방향 데이터 바인딩이 서포트되고 있습니다만 RxSwift의 문서에는 그러한 기술은 없고, 깨끗하게 쓰는 방법 없을까~라고 Examples를 바라보고 있으면 그것 같은 것을 발견했으므로 소개합니다.

하는 일




  • 등장 인물
  • 라벨
  • 최신 값을 계속 표시


  • 텍스트 필드 ←이 녀석에게 양방향 bind를 구현합니다.
  • 최신 값을 계속 표시
  • 값을 입력할 수 있습니다

  • 버튼
  • 값을 초기 값으로 변경할 수 있습니다



  • 이 UI에서,

  • 텍스트 필드에 입력한 내용이 즉시 라벨에 반영된다.
  • 버튼을 누르면 다시 작성된 내용이 즉시 텍스트 필드에 반영됩니다.

  • 라는 점에서 양방향 데이터 바인딩을 실현해 보겠습니다.

    Before


    import UIKit
    import RxSwift
    import RxCocoa
    
    class ViewController: UIViewController {
        private var item = Variable<String?>("Hello!")
        private let disposeBag = DisposeBag()
    
        @IBOutlet weak var label: UILabel!
        @IBOutlet weak var textField: UITextField!
    
        @IBAction func resetButtonHandler(_ sender: UIButton) {
            item.value = "Hello!"
        }
    
        @IBAction func textFieldHandler(_ sender: UITextField) {
            item.value = sender.text
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            setup()
        }
    
        private func setup() {
            // モデルからビューへ
            item.asObservable().bind(to: textField.rx.text).disposed(by: disposeBag)
            // ビューからモデルへ
            textField.rx.text.subscribe(onNext: { [weak self] text in
                self?.item.value = text
            }).disposed(by: disposeBag)
    
            // 最新の値をラベルで表示しておく
            item.asObservable().bind(to: label.rx.text).disposed(by: disposeBag)
        }
    }
    

    여기서 Bidirectional Operator <-> 의 등장입니다.

    왼쪽에 보기, 오른쪽에 모델이 오도록 씁니다.
    게다가 그대로라면 반환값이 미사용이라고 말하기 때문에 _ = 를 선두에 붙여 둡니다.
    (일단 예에도 그렇게 썼습니다만, 만일 메모리 누수의 위험성 밟으면 가르쳐 주고 싶다...! )

    After


    import UIKit
    import RxSwift
    import RxCocoa
    
    class ViewController: UIViewController {
        private var item = Variable<String?>("Hello!")
        private let disposeBag = DisposeBag()
    
        @IBOutlet weak var label: UILabel!
        @IBOutlet weak var textField: UITextField!
    
        @IBAction func resetButtonHandler(_ sender: UIButton) {
            item.value = "Hello!"
        }
    
        @IBAction func textFieldHandler(_ sender: UITextField) {
            item.value = sender.text
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            setup()
        }
    
        private func setup() {
            _ = textField.rx.text <-> item // ここ(´∀` )
            item.asObservable().bind(to: label.rx.text).disposed(by: disposeBag)
        }
    }
    

    유저 ID+패스워드나, 주소 성명 연령 전화 번호···와 ​​같은 설정하는 컴퍼넌트가 많은 화면에서 활약해 줄 것 같습니다!
    점점 RxSwift가 재밌게 된 오늘 요즘 잘자.

    좋은 웹페이지 즐겨찾기