iOS プロジェクトでは、スライダーとテキスト フィールドを同時に使用して float 値を選択できるビュー コントローラーを実装する必要があります。次の動作が必要です。
- テキストフィールドに数値が入力されるたびに、スライダーはその値を入力された浮動小数点数に更新する必要があります
- スライダーがドラッグされるたびに、スライダーの値でテキストフィールドを更新する必要があります
現在のアイデアは次のとおりです。
ビュー モデルには、実際の値と値のテキストという 2 つのプロパティがあります。値が更新されるたびに、ビューモデル内のテキストを更新します。テキスト フィールドとスライダーの両方が値のみを変更します。しかし、私は一種の「循環的な」依存関係を持っています。テキストフィールドはビューモデルの値を更新し、ビューモデルのテキストを更新します。これは、値を入力するだけのテキストフィールドにバインドされています。これにより、テキスト フィールドの動作にバグが発生します。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
})
私のビュー モデル:
import ReactiveSwift
class ValuePickerViewModel {
var valueText: MutableProperty<String>
var value: MutableProperty<Float>
let minValue: Float
let maxValue: Float
let unit: String
init(initialValue: Float, formatter: FloatFormatter, minValue: Float, maxValue: Float, unit: String) {
self.value = MutableProperty(initialValue)
self.valueText = MutableProperty(formatter.format(value: initialValue))
self.valueText <~ self.value.map({value in
formatter.format(value: value)
}
)
self.minValue = minValue
self.maxValue = maxValue
self.unit = unit
}
}