How to Detect Delete Key on an Uitextfield in iOS 8

How to detect delete key on an UITextField in iOS 8?

You must look an example for MBContactPicker on github. Deletion of contacts at MBContactPicker via Backspace button on iOS8 tested by me. And it works greatly! You can use its as example.

Author of MBContactPicker use next method: When UITextField must become empty (or before call becomeFirstResponder when it is empty), he save single whitespace symbol there. And then when you press Backspace button (when focus was set to end of text of your UITextField), method

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

will work. Inside it you must use check like this:

NSString *resultString = [textField.text stringByReplacingCharactersInRange:range withString:string];
BOOL isPressedBackspaceAfterSingleSpaceSymbol = [string isEqualToString:@""] && [resultString isEqualToString:@""] && range.location == 0 && range.length == 1;
if (isPressedBackspaceAfterSingleSpaceSymbol) {
// your actions for deleteBackward actions
}

So, you must always control that UITextField contains single whitespace.

This is not hack. So, user willn't noticed about some behaviour was changed

Can I detect the delete key even if the UITextField is empty?

Its possible to put a button over it, but that's a bit fragile since keyboard layout could change with different iOS versions and there certainly are different keyboard layouts for different languages.

Look at the "Managing Text Fields and Text Views" Apple doc. Im sure there is a way to do this. Its something like a UITextField implements a protocol to get keyevents. One of those key events will probably be a delete key, so you could override whatever method receives these and get it that way.

Detect backspace in empty UITextField

This may be a long shot but it could work. Try setting the text field's text to a zero width space character \u200B. When backspace is pressed on a text field that appears empty, it will actually delete your space. Then you can just reinsert the space.

May not work if the user manages to move the caret to the left of the space.

Detect backspace Event in UITextField

Swift 4.2

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let char = string.cString(using: String.Encoding.utf8) {
let isBackSpace = strcmp(char, "\\b")
if (isBackSpace == -92) {
print("Backspace was pressed")
}
}
return true
}

Older Swift version

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let char = string.cStringUsingEncoding(NSUTF8StringEncoding)!
let isBackSpace = strcmp(char, "\\b")

if (isBackSpace == -92) {
println("Backspace was pressed")
}
return true
}

UITextField How to check if a delete key is pressed

You can get the string that is supposed to be in text field after this method:

NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

And that newString you probably can use 'as is' for searching the database.

If you just want to get the event when user deletes some characters in textField - then you can check it the following way:

if ([string length] == 0 && range.length > 0)
//Some characters deleted

How to know when the delete button on decimal pad is clicked

edit/update:

Xcode 11 • Swift 5.2 or later

Follow up on this question and Swift 5 syntax can be found on this post


Original answer

Swift 1.x

Following up Istvan answer, you need to post a notification when the deleteBackward is pressed:

class DigitField: UITextField {
override func deleteBackward() {
super.deleteBackward()
NSNotificationCenter.defaultCenter().postNotificationName("deletePressed", object: nil)
}

}

Then inside viewDidLoad() you add an observer as follow:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "goPrevious", name: "deletePressed", object: nil)

and your method:

func goPrevious() {
if secondDigit.isFirstResponder() {
secondDigit.enabled = false
firstDigit.enabled = true
firstDigit.becomeFirstResponder()
} else if thirdDigit.isFirstResponder() {
thirdDigit.enabled = false
secondDigit.enabled = true
secondDigit.becomeFirstResponder()
} else if fourthDigit.isFirstResponder() {
fourthDigit.enabled = false
thirdDigit.enabled = true
thirdDigit.becomeFirstResponder()
}
}

Select your text field and connect it to your DigitField

Sample Image

You need to connect each text field to an IBAction (using sent events editing changed)

Sample Image

The view controller code should look like this:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var firstDigit: UITextField!
@IBOutlet weak var secondDigit: UITextField!
@IBOutlet weak var thirdDigit: UITextField!
@IBOutlet weak var fourthDigit: UITextField!

override func viewDidLoad() {
super.viewDidLoad()

NSNotificationCenter.defaultCenter().addObserver(self, selector: "goPrevious", name: "deletePressed", object: nil)

firstDigit.secureTextEntry = true
secondDigit.secureTextEntry = true
thirdDigit.secureTextEntry = true
fourthDigit.secureTextEntry = true

firstDigit.keyboardType = .DecimalPad
secondDigit.keyboardType = .DecimalPad
thirdDigit.keyboardType = .DecimalPad
fourthDigit.keyboardType = .DecimalPad

firstDigit.becomeFirstResponder()
secondDigit.enabled = false
thirdDigit.enabled = false
fourthDigit.enabled = false
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

func goPrevious() {
if secondDigit.isFirstResponder() {
secondDigit.enabled = false
firstDigit.enabled = true
firstDigit.becomeFirstResponder()
} else if thirdDigit.isFirstResponder() {
thirdDigit.enabled = false
secondDigit.enabled = true
secondDigit.becomeFirstResponder()
} else if fourthDigit.isFirstResponder() {
fourthDigit.enabled = false
thirdDigit.enabled = true
thirdDigit.becomeFirstResponder()
}
}
// You need to connect each text field to an IBAction (using sent events editing changed) –
@IBAction func firstChanged(sender: UITextField) {
if let digitOne = sender.text.toInt() {
println(digitOne)
sender.enabled = false
secondDigit.enabled = true
secondDigit.becomeFirstResponder()
} else {
sender.text = ""
}
}

@IBAction func secondChanged(sender: UITextField) {
if let digitTwo = sender.text.toInt() {
println(digitTwo)
sender.enabled = false
thirdDigit.enabled = true

thirdDigit.becomeFirstResponder()
} else {
sender.text = ""
}
}

@IBAction func thirdChanged(sender: UITextField) {
if let digitThree = sender.text.toInt() {
println(digitThree)
sender.enabled = false
fourthDigit.enabled = true
fourthDigit.becomeFirstResponder()
} else {
sender.text = ""
}
}

@IBAction func fourthChanged(sender: UITextField) {
if let digitFour = sender.text.toInt() {
println(digitFour)
sender.enabled = false
} else {
sender.text = ""
}
}
}

Swift 4 how to know delete key is pressed when UITextField becomes first responder?

This can be done using multiple methods(not straight though!). One is to put an invisible button over it, or by subclassing UITextField and adding it as a custom class of the desired textfield. Then override the method deleteBackward. This method will catch all the backspace events.

Subclass UITextField:

// MyTextField.swift

import UIKit

protocol MyTextFieldDelegate {
func textFieldDidDelete()
}

class MyTextField: UITextField {

var myDelegate: MyTextFieldDelegate?

override func deleteBackward() {
super.deleteBackward()
myDelegate?.textFieldDidDelete()
}

}

Implementation:

// ViewController.swift

import UIKit

class ViewController: UIViewController, MyTextFieldDelegate {

override func viewDidLoad() {
super.viewDidLoad()

// initialize textField
let input = MyTextField(frame: CGRect(x: 50, y: 50, width: 150, height: 40))

// set viewController as "myDelegate"
input.myDelegate = self

// add textField to view
view.addSubview(input)

// focus the text field
input.becomeFirstResponder()
}

func textFieldDidDelete() {
print("delete")
}

}


Related Topics



Leave a reply



Submit