ios - Swift 2 RAC4 合并 UITextField 信号和 UISwitch 信号

标签 ios swift merge reactive-cocoa reactive-cocoa-4

我已经编写了代码的 react 命令式版本:

widthTextField.rac_textSignal().subscribeNext { (val) in
    let multiplier = 0.2
    if var v = Double(val as! String){
        if(self.viewModel.proportionalBool.value){
            v *= multiplier
            self.heightTextField.text = String(v)
        }
    }
}

我的 ViewModel 中有三个 MutableProperties:Bool 类型的 proportionalBool、heightString 和 String 类型的 widthString。

我的 ViewController 中也有一个相应的 UISwitch 和两个 UITextField。

我想学习的是以下场景: 1. 如果 bool/switch 为 false,则 heightString 应该保持不变 2. 如果bool为true,那么heightString的值应该是:widthString * multiplier

我知道我写的代码很糟糕。我想我应该使用 combineLatest 但我不知道如何将两个信号:UITextField 和 UISwitch 合并为一个生成信号。

谁能给我任何提示或简单的代码示例?

let boolSignal = proportionalSwitch.rac_newOnChannel()
let widthSignal = widthTextField.rac_textSignal()
let heightSignal = heightTextField.rac_textSignal()
...?

最佳答案

我假设您始终希望 ViewModel 中的 MutableProperties 始终具有正确的值。

另外,我将使用 REX ( which will soon be a part of RAC anyway ) 用于更简单的 UI 绑定(bind)。

假设这是您的 viewModel:

final class ViewModel {
    let on = MutableProperty<Bool>(false)
    let width = MutableProperty<Double>(0.0)
    let height = MutableProperty<Double>(0.0)
}

第一部分是将开关和文本字段绑定(bind)到 viewModel 的 MutableProperties。

前两个相对简单:

viewModel.on <~ onSwitch.rex_on
viewModel.width <~ widthTextField.rex_textSignal
    .map { Double($0) ?? 0 }

注意:如果宽度文本字段的输入不是有效数字,我选择发送 0 作为宽度。根据您的需要,您可能希望以不同方式处理这种情况,例如通过使 widthheight 属性具有可选值...

现在高度几乎相同,但我们必须确保它只在开关打开时处理。这是通过使用 combineLatestfilter 实现的:

viewModel.height <~ combineLatest(viewModel.on.producer, viewModel.width.producer)  // SignalProducer<(Bool, Double), NoError>
    .filter { on, text in return on }   // Only send values when the switch is `on`
    .map { on, width in return width }  // Now we dont care about the switch value anymore, extract just the width
    .map { width in return 0.5 * width }// Transform the width as you wish

现在,剩下的就是将高度值绑定(bind)到 UI。除非我遗漏了什么,否则 REX 对此没有帮助(至少 UITextField 没有),所以我们将不得不使用 DynamicProperty:

override func viewDidLoad() {
    super.viewDidLoad()

    // Previously mentioned binding to the viewModel

    DynamicProperty(object: heightTextField, keyPath: "text") <~ viewModel.height.producer.map { String($0) }
}

关于ios - Swift 2 RAC4 合并 UITextField 信号和 UISwitch 信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37174772/

相关文章:

Swift MLDataTable - 如何删除行?

ios - 在 iOS 中使用 AVAudioEngine 的默认音频输出

javascript - 合并来自具有相同键的不同对象的数组

ios - 如何在 Swift 中从不同于 (0, 0) 的坐标开始?

iphone - 追加字符串时的内存管理?

iphone - PageViewController 当前索引

python - 合并非唯一列 - pandas python

ios - 在 Here-API 中,我们如何在 MapView 中显示下载的区域包 NMAMapLoader?

ios - 为什么它会覆盖数据而不是在 firebase 中添加更多数据?

git - 此工作流程如何导致工作被丢弃?