Ios 使用ReactiveCocoa的循环绑定,如何将一个值绑定到两个输入UI元素

Ios 使用ReactiveCocoa的循环绑定,如何将一个值绑定到两个输入UI元素,ios,swift,reactive-programming,reactive-swift,reactive-cocoa-5,Ios,Swift,Reactive Programming,Reactive Swift,Reactive Cocoa 5,在iOS项目中,我必须实现一个视图控制器,允许同时使用滑块和文本字段拾取浮点值。它应该具有以下行为: 无论何时在文本字段中键入数字,滑块都应将其值更新为键入的浮点数 无论何时拖动滑块,都应使用滑块值更新文本字段 目前的想法如下: 视图模型中有两个属性:实际值和值文本。 每当更新值时,我都会更新视图模型中的文本。 文本字段和滑块仅更改值。 但是我有一种“循环”依赖关系:文本字段更新视图模型值,它更新视图模型文本,它绑定到文本字段,我们只是在其中键入值。这会导致文本字段出现错误行为。我尝试使用i

在iOS项目中,我必须实现一个视图控制器,允许同时使用滑块和文本字段拾取浮点值。它应该具有以下行为:

  • 无论何时在文本字段中键入数字,滑块都应将其值更新为键入的浮点数
  • 无论何时拖动滑块,都应使用滑块值更新文本字段
目前的想法如下:

视图模型中有两个属性:实际值和值文本。 每当更新值时,我都会更新视图模型中的文本。 文本字段和滑块仅更改值。 但是我有一种“循环”依赖关系:文本字段更新视图模型值,它更新视图模型文本,它绑定到文本字段,我们只是在其中键入值。这会导致文本字段出现错误行为。我尝试使用isFirstResponder属性,它工作得更好,但似乎不是最佳实践,而且它也不是预期的。 有没有办法将滑块的enabledProperty绑定到文本字段的isFirstResponder?这也会起作用

VC中的绑定:

       layout.valueTextField.reactive.text <~ viewModel.valueText.map( { text in
        if !self.layout.valueTextField.isFirstResponder {
            return text
        }
        return self.layout.valueTextField.text ?? ""
        }
    )
    viewModel.value <~ layout.valueSlider.reactive.values
    layout.valueSlider.reactive.value <~ viewModel.value
    viewModel.value <~ layout.valueTextField.reactive.continuousTextValues.map({ textValue in
        if let t = textValue {
            if let parsed = Float(t) {
                return parsed
            }
        }
        return viewModel.value.value
    })
layout.valueTextField.reactive.text解决方案很简单:
textFields值绑定到视图模型浮动值。
“幻灯片”值绑定到“视图模型”文本值。
因此,每个组件都会更新另一个组件,没有循环

工作代码:

绑定:

    viewModel.value <~ layout.valueTextField.reactive.continuousTextValues.map({ textValue in
        if let t = textValue {
            if let parsed = Float(t) {
                return parsed
            }
        }
    return viewModel.value.value
    })
    viewModel.valueText <~ layout.valueSlider.reactive.values.map({ value in
        return viewModel.formatter.format(value: value)
    })
    layout.valueSlider.reactive.value <~ viewModel.value
    layout.valueTextField.reactive.text <~ viewModel.valueText
viewModel.value
    viewModel.value <~ layout.valueTextField.reactive.continuousTextValues.map({ textValue in
        if let t = textValue {
            if let parsed = Float(t) {
                return parsed
            }
        }
    return viewModel.value.value
    })
    viewModel.valueText <~ layout.valueSlider.reactive.values.map({ value in
        return viewModel.formatter.format(value: value)
    })
    layout.valueSlider.reactive.value <~ viewModel.value
    layout.valueTextField.reactive.text <~ viewModel.valueText
import ReactiveSwift

class ValuePickerViewModel {

var valueText: MutableProperty<String>
var value: MutableProperty<Float>
let minValue: Float
let maxValue: Float
let unit: String
let formatter: FloatFormatter

init(initialValue: Float, formatter: FloatFormatter, minValue: Float, maxValue: Float, unit: String) {
    self.formatter = formatter
    self.value = MutableProperty(initialValue)
    self.valueText = MutableProperty(formatter.format(value: initialValue))
    self.minValue = minValue
    self.maxValue = maxValue
    self.unit = unit
}

}