Как можно разделить значение между локальной переменной @State и @Binding в SwiftUI? - PullRequest
0 голосов
/ 04 февраля 2020
import SwiftUI

enum ValueType {
    case string(String)
    case int(Int)
}

struct ParentView: View {
    @State var value: ValueType?

    var body: some View {
        ChildView(boundValue: $value)
    }
}

struct ChildView: View {
    @Binding var boundValue: ValueType?

    @State private var userInput: String = ""

    var body: some View {
        TextField("Enter some text", text: $userInput)
    }
}

Здесь ChildView имеет связанную версию родительского элемента @State ... answer var. Однако конкретный вариант использования c здесь включает в себя привязку перечисления, которое может иметь значение String или Int, тогда как ChildView имеет значение TextField, которое включает чистое значение String. Как можно передать значение ChildView userInput в boundValue.string(...)?

Спасибо за чтение. Извиняюсь, если этот вопрос является дубликатом, я искал, но ничего не нашел.

Ответы [ 2 ]

3 голосов
/ 04 февраля 2020

Инициализатор TextField также имеет два необязательных аргумента для обратных вызовов, onEditingChanged и onCommit, поэтому другой подход может заключаться в том, чтобы поместить туда ваши обновления * c.

TextField("Enter some text", text: $userInput, onCommit: {
    self.boundValue = .string(self.userInput)
})
0 голосов
/ 04 февраля 2020

Вы можете использовать второе связывание, чтобы связать строку с вашим пользовательским перечислением, если вы обрабатываете все случаи. Вот пример:

import SwiftUI

enum ValueType {
  case string(String)
  case int(Int)
}

struct ParentView: View {
  @State var value: ValueType?
  var body: some View {
    ChildView(boundValue: $value)
  }
}

struct ChildView: View {
  let boundValue: Binding<ValueType?>
  let myCustomBinding: Binding<String>
  init(boundValue: Binding<ValueType?>) {
      myCustomBinding = Binding<String>.init(
      get: {
        switch boundValue.wrappedValue {
        case .string(let string):
          return string
        case .int(let int):
          return String(describing: int)
        case .none:
          return ""
        }
      },
      set: { (string: String) -> Void in
        boundValue.wrappedValue = Int(string).map{ ValueType.int($0)} ?? ValueType.string(string)
      })
    self.boundValue = boundValue.projectedValue
  }

  var body: some View {
    TextField("Enter some text", text: myCustomBinding)
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...