7

I'm using SwiftUI, but I'm coding my own custom text mask, but I need to delete when a user press the "delete" key. I'm using the onChange method, but it is not detecting when special keys are pressed. Currently I'm using:

TextField(self.placeholder, text: self.$text)
.onChange(of: self.text, perform: { value in
    print(value)
})

Is there a way to detect if the delete button is pressed? Or should I use the UITextField instead of TextField ?

3

2 Answers 2

4

Well you could use a hacky way for this.

  • First we will hold a count of the current characters the text string has.
  • Whenever the user presses backspace we check in the onChange handler if the previous character count is higher than the new character count
  • if that is the case we delete the whole string, or whatever you want to do when the delete button is pressed.
import SwiftUI
struct SquareView: View {
    
    var placeholder = "test"
    @State var text = "test"
    @State var textLen = 4
    
    var body: some View {
        VStack {
            TextField(self.placeholder, text: self.$text)
            .onChange(of: self.text, perform: { value in
                if value.count < textLen {
                    self.text = "" // << removed the whole text but here you can insert anything you want to do when the delete button is pressed
                }
                textLen = value.count
            })
        }
    }
}

Keep in mind that this is a hacky way and brings risks. For example if users paste something which is shorter than the current text.

Sign up to request clarification or add additional context in comments.

1 Comment

.onChange is not triggered when the user presses backspace.
2

MVVM + Combine way:

class RecoveryPasswordViewModel: ObservableObject {
  @Published var email: String = ""
  @Published var isValidTextFieldStatus = true
  var cancellables = Set<AnyCancellable>()

  init() {
    setTextFieldToValidWhenUserDelete()
  }

  func setTextFieldToValidWhenUserDelete() {
    $email
        .scan("", { [weak self] previousInput, currentInput in
            if previousInput.count > currentInput.count {
                self?.isValidTextFieldStatus = true
            }
            return currentInput
        })
        .sink { _ in }
        .store(in: &cancellables)
 }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.