How to detect backspace in SwiftUI TextField without falling back to UIViewRepresentable?

I'm building a multi-box PIN/OTP input in SwiftUI. In UIKit, I used UITextFieldDelegate to detect backspace presses on an empty field to move focus backward.

SwiftUI’s .onChange(of: text) only triggers when text is actually deleted, completely missing backspaces on an already empty field.

Is there a pure SwiftUI way to handle this now, or are we still forced to wrap UITextField via UIViewRepresentable?

You may use .onKeyPress:

struct ContentView: View {
    @State private var vText: String = ""

    var body: some View {
        HStack {
            TextField("Enter text", text: Binding(
                get: { vText },
                set: { newValue in
                    vText = newValue
                }
            ))
            .onChange(of: vText) { oldText, newText in
                let typed = newText.replacingOccurrences(of: oldText, with: "")
                if newText.count < oldText.count {
                    print("backspace")
                } else {
                    print("typed char is: ", typed)
                }
            }
        }
        .onKeyPress(characters: .controlCharacters, action: { keyPress in
            if vText.count == 0 {
                print("Control key \(keyPress.characters)")
                // Do whatever needed and test if backspace
            }
            return .ignored // handled would intercept the typing
        })
    }
}

Let us know if that works (don't forget to close the thread if so).

How to detect backspace in SwiftUI TextField without falling back to UIViewRepresentable?
 
 
Q