Home > Blockchain >  SwiftUI how to deal with onEditingChanged for text field
SwiftUI how to deal with onEditingChanged for text field

Time:03-02

I used to use this TextField API for editing change callback (example usage: to check if input is valid after done editing):

init(_ titleKey: LocalizedStringKey, text: Binding<String>, onEditingChanged: @escaping (Bool) -> Void, onCommit: @escaping () -> Void)

It's marked as deprecated in the doc, with a explanation:

Use init(_:text:prompt:) instead. Add the onSubmit(of:_:) view modifier for the onCommit behavior. Use FocusState and focused(_:equals:) for the onEditingChanged behavior.

I am not sure how to use focused(_:equals:) for onEditingChanged. It does not have a callback when this field is done editing.


struct MyTextField {
  let binding: Binding<Text>

  var body: some View {
    TextField("Enter Amount", text: binding) // there used to be a `onEditingChanged` callback here, but it's deprecated. 
      .keyboardType(.decimalPad)
  }
}

enum Field {
  case heightField
  case weightField
}


struct HomeView {

  @FocusState
  private var focusedField: Field?

  var body: some View {

    MyTextField(binding: $height) 
      .focused($focusedField, equals:.heightField)

    MyTextField(binding: $weight)
      .focused($focusedField, equals:.weightField)

  }
}

I have seen this question but i think it's outdated How to detect when a TextField loses the focus in SwiftUI for iOS?

CodePudding user response:

This should work

struct MyCustomTextField<Tag: Hashable> {
  private let tag: Tag
  private let focusedField: FocusState<Tag>.Binding

  public var body: some View {
    let oldFocusedTag = focusedField.wrappedValue
    TextField(...)
      .focused(focusedField, equals: tag)
      .onChange(of: focusedField.wrappedValue, perform: { newFocusedTag in
        if oldFocusedTag != newFocusedTag {
          let loseFocus = oldFocusedTag == tag
          let gainFocus = newFocusedTag == tag
          // ...
        }
      })
  • Related