0

コードの反応命令型バージョンを作成しました。

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 に持っているのは、3 つの MutableProperties です: Bool 型の比例ブール、String 型の heightString および widthString です。

ViewController には、対応する UISwitch と 2 つの UITextField もあります。

私が学びたいのは、次のシナリオを持つことです: 1. bool/switch が false の場合、heightString はそのままにする必要があります 2. bool が true の場合、heightString は次の値である必要があります: widthString * 乗数

私は悪い方法でコードを書いたことを知っています。CombineLatest を使用するべきだったと思いますが、UITextField と UISwitch の 2 つのシグナルを 1 つの生成シグナルにマージする方法がわかりません。

ヒントや簡単なコード例を教えてもらえますか?

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

1 に答える 1

1

ViewModel の MutableProperties には常に正しい値が必要であると仮定します。

また、より単純な UI バインディングのためにREX (いずれにせよまもなく RAC の一部になる予定です) を使用します。

これがあなたのviewModelだとしましょう:

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

最初の部分は、スイッチとテキスト フィールドを viewModel の MutableProperties にバインドします。

最初の 2 つは比較的単純です。

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

注:幅テキストフィールドの入力が有効な数値でない場合、幅として 0 を送信することにしました。必要に応じて、このケースを別の方法で処理したい場合があります。たとえば、widthおよびheightプロパティにオプションの値を持たせるなど...

これで高さはほぼ同じになりましたが、スイッチがオンのときにのみ処理されるようにする必要があります。これは、 と を使用して実現されcombineLatestますfilter

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

あとは、高さの値を 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) }
}
于 2016-05-15T12:13:25.317 に答える