0

iOSプロジェクトでは、スライダを使用してfloat値を選択できるビューコントローラを実装する必要があります同時にテキストフィールド。番号がテキストフィールドに入力されるたびに、スライダーは、それがスライダーをドラッグするたびに、それがテキストフィールドを更新する必要があります入力された浮動小数点数 ReactiveCocoaでの循環バインディング、1つの値を2つの入力UI要素にバインドする方法

  • に値です更新する必要があり

    • :それは次のように動作している必要があり次のようにスライダ値

    現在の考え方は次のとおりです。

    私はビューモデル、実際の値と値のテキストで2 propertysを持っています。 値が更新されるたびに、私はビューモデル内のテキストを更新します。 テキストフィールドとスライダの両方が値のみを変更します。 しかし、私は一種の「循環」依存関係を持っています。テキストフィールドはビューモデルの値を更新し、ビューモデルのテキストを更新します。これは値を入力するテキストフィールドにバインドされています。これは、テキストフィールドのバグのある動作につながります。私は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 
    } 
    
    } 
    
  • 答えて

    1

    解決策は単純です: テキストフィールドの値は、モデルが値をフロートビューに結合します。 スライドの値はビューモデルのテキスト値にバインドされます。 各コンポーネントはもう一方のコンポーネントを更新し、サイクルはありません!

    の作業コード:

    バインディング:

    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:

    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 
    } 
    
    } 
    
    関連する問題