zoukankan      html  css  js  c++  java
  • ReactiveX 学习笔记(33)使用 RxSwift + RxCocoa + MVVM 进行 GUI 编程

    课题

    1. 程序界面由3个文本编辑框和1个文本标签组成。
    2. 要求文本标签实时显示3个文本编辑框所输入的数字之和。
    3. 文本编辑框输入的不是合法数字时,将其值视为0。
    4. 3个文本编辑框的初值分别为1,2,3。

    创建工程

    打开 Xcode,File / New / Project..
    在 New Project 向导的第1页,选 iOS / Single View App
    在向导的第2页填上 Product Name: RxExample
    在向导的第3页选择任意文件夹点击 Create 按钮创建工程
    关闭所创建的工程

    配置 Pods

    在工程所在文件夹下创建 Podfile 文件,内容如下:

    use_frameworks!
    
    target 'RxExample' do
    project 'RxExample'
    pod 'RxSwift'
    pod 'RxCocoa'
    pod 'RxBinding'
    pod 'NSObject+Rx'
    end
    

    打开终端在工程所在文件夹下执行 pod install 命令。

    $ cd RxExample
    $ pod install
    ...
    Installing NSObject+Rx (5.1.0)
    Installing RxBinding (0.4)
    Installing RxCocoa (5.1.1)
    Installing RxSwift (5.1.1)
    ...
    

    打开 TwoWayBind.swift 文件,添加 BehaviorRelay<String> 专用的 <~> 操作符函数

    public func <~> <T>(relay: BehaviorRelay<String>, textInput: TextInput<T>) -> Disposable {
        return relay.twoWaybind(to: textInput)
    }
    

    用 Xcode 打开 RxExample.xcworkspace

    配置 UI

    打开 Main.storyboard 文件,在 View Controller Scene / View Controller / View 下面放置3个 Text Field 和1个 Label。

    控件变量

    打开 ViewController.swift 文件,在 ViewController 类中添加控件变量

    @IBOutlet weak var tfNumber1: UITextField!
    @IBOutlet weak var tfNumber2: UITextField!
    @IBOutlet weak var tfNumber3: UITextField!
    @IBOutlet weak var lblResult: UILabel!
    

    使用 Assistant Editor 同时打开 Main.storyboard 文件,用 Control 键将控件变量挂到相应的控件上。

    使用 MVVM 的解决方案

    在 ViewController.swift 文件中添加 RxSwift RxCocoa RxBinding NSObject_Rx 的引用。

    import UIKit
    import RxSwift
    import RxCocoa
    @_exported import RxBinding
    import NSObject_Rx
    

    在 ViewController.swift 文件中添加 NumbersViewModel 类

    class NumbersViewModel: NSObject {
        var number1 = BehaviorRelay(value: "1")
        var number2 = BehaviorRelay(value: "2")
        var number3 = BehaviorRelay(value: "3")
        var result = BehaviorRelay(value: "")
        
        override init() {
            super.init()
            Observable.combineLatest(number1, number2, number3) { num1, num2, num3 -> Int in
                (Int(num1) ?? 0) + (Int(num2) ?? 0) + (Int(num3) ?? 0) }
                .map { String($0) }
                ~> result
                ~ rx.disposeBag
        }
    }
    

    在 ViewController 类添加 NumbersViewModel 类的实例,并且在 viewDidLoad 方法中添加绑定控件的代码

    class ViewController: UIViewController {
    // ...
        var vm: NumbersViewModel!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            vm = NumbersViewModel()
            vm.number1 <~> tfNumber1.rx.textInput ~ rx.disposeBag
            vm.number2 <~> tfNumber2.rx.textInput ~ rx.disposeBag
            vm.number3 <~> tfNumber3.rx.textInput ~ rx.disposeBag
            vm.result ~> lblResult.rx.text ~ rx.disposeBag
        }
    // ...
    }
    
  • 相关阅读:
    qt5--数据类型转换
    qt5-QWidget坐标系统和大小和展示区域
    qt5---布局
    qt5-信号和槽
    tomcat中文请求乱码问题
    centos安装ab测试工具
    golang学习之go简单博客应用
    nodejs的jsonrpc调用
    centos下mongodb安装
    使用connect-multiparty限制nodejs图片上传
  • 原文地址:https://www.cnblogs.com/zwvista/p/13369779.html
Copyright © 2011-2022 走看看