检测UITextField中的退格

有没有什么办法来检测在空的UITextField的iPhone键盘上按下Backspace / Delete键? 我想知道什么时候只有在UITextField为空时才按下Backspace


基于@Alex Reynolds的build议,我在创build文本字段时添加了以下代码:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTextFieldChanged:) name:UITextFieldTextDidChangeNotification object:searchTextField]; 

收到此通知(调用handleTextFieldChanged函数),但仍然不是当我在空字段中按Backspace键时。 有任何想法吗?


这个问题似乎有些困惑。 我想在按Backspace键时收到通知。 而已。 但是解决scheme也必须在UITextField已经为空的情况下工作。

这可能是一个长镜头,但它可以工作。 尝试将文本字段的文本设置为零宽度空格字符\u200B 。 当在显示为空的文本字段上按下退格键时,它实际上会删除您的空间。 那么你可以重新插入空间。

如果用户设法将光标移动到空间的左侧,可能无法工作。

子类UITextField

 //Header //MyTextField.h //create delegate protocol @protocol MyTextFieldDelegate <NSObject> @optional - (void)textFieldDidDelete; @end @interface MyTextField : UITextField<UIKeyInput> //create "myDelegate" @property (nonatomic, assign) id<MyTextFieldDelegate> myDelegate; @end //Implementation #import "MyTextField.h" @implementation MyTextField - (void)deleteBackward { [super deleteBackward]; if ([_myDelegate respondsToSelector:@selector(textFieldDidDelete)]){ [_myDelegate textFieldDidDelete]; } } @end 

现在只需将MyTextFieldDelegate添加到您的UIViewController ,并将您的UITextFields myDelegate设置为self

 //View Controller Header #import "MyTextField.h" //add "MyTextFieldDelegate" to you view controller @interface ViewController : UIViewController <MyTextFieldDelegate> @end //View Controller Implementation - (void)viewDidLoad { //initialize your text field MyTextField *input = [[MyTextField alloc] initWithFrame:CGRectMake(0, 0, 70, 30)]; //set your view controller as "myDelegate" input.myDelegate = self; //add your text field to the view [self.view addSubview:input]; } //MyTextField Delegate - (void)textFieldDidDelete { NSLog(@"delete"); } 

更新:请参阅JacobCaraballo的答案 ,覆盖范例-[UITextField deleteBackward]

查看UITextInput ,特别是UIKeyInput有一个deleteBackward委托方法 ,当按下delete键时总是被调用。 如果你正在做一些简单的事情,那么你可以考虑UIKeyInput UILabel并使其符合UIKeyInput协议,就像SimpleTextInput和这个iPhone UIKeyInput示例所做的那样 。 注意: UITextInput及其亲属(包括UIKeyInput )仅在iOS 3.2及更高版本中可用。

代码如下:

 @interface MyTextField : UITextField @end @implementation MyTextField - (void)deleteBackward { [super deleteBackward]; //At here, you can handle backspace key pressed event even the text field is empty } @end 

最后,忘记将文本字段的自定义类属性更改为“MyTextField”

我创build其他方式比subclass解决scheme更容易。 即使它有点奇怪,但它工作正常。

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { const char * _char = [text cStringUsingEncoding:NSUTF8StringEncoding]; int isBackSpace = strcmp(_char, "\b"); if (isBackSpace == -8) { // is backspace } return YES; } 

比较结果是-8有点奇怪。 也许我会在C Programming某个地方出错。 但是正确的工作;)

快速实施:

 import UIKit protocol PinTexFieldDelegate : UITextFieldDelegate { func didPressBackspace(textField : PinTextField) } class PinTextField: UITextField { override func deleteBackward() { super.deleteBackward() // If conforming to our extension protocol if let pinDelegate = self.delegate as? PinTexFieldDelegate { pinDelegate.didPressBackspace(self) } } } 

试试delegate

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

然后检查是否range.length == 1这似乎是backspace被击中的情况。

Niklas Alvaeus的回答帮助我解决了类似的问题

我限制了进入一个特定的字符集,但它忽略了退格。 所以我在修剪NSString之前检查了range.length == 1 。 如果这是真的,我只是返回string,不要修剪它。 见下文

  - (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet]; if (range.length == 1) { return string; } else { return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0); } } 

请使用下面的代码,它将帮助您检测键盘删除键,即使您的文本框是空的。

目标C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { return YES; }

swift 3.0:

 func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true } 

对于那些对雅各答案有疑问的人,我实现了我的文本字段子类,如下所示:

 #import <UIKit/UIKit.h> @class HTTextField; @protocol HTBackspaceDelegate <NSObject> @optional - (void)textFieldDidBackspace:(HTTextField*)textField; @end @interface HTTextField : UITextField<UIKeyInput> @property (nonatomic, assign) id<HTBackspaceDelegate> backspaceDelegate; @end #import "HTTextField.h" @implementation HTTextField - (void)deleteBackward { [super deleteBackward]; if ([self.backspaceDelegate respondsToSelector:@selector(textFieldDidBackspace:)]){ [self.backspaceDelegate textFieldDidBackspace:self]; } } - (BOOL)keyboardInputShouldDelete:(UITextField *)textField { BOOL shouldDelete = YES; if ([UITextField instancesRespondToSelector:_cmd]) { BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd]; if (keyboardInputShouldDelete) { shouldDelete = keyboardInputShouldDelete(self, _cmd, textField); } } if (![textField.text length] && [[[UIDevice currentDevice] systemVersion] intValue] >= 8) { [self deleteBackward]; } return shouldDelete; } @end 

我发现用于检测退格键的最佳用法是检测用户何时在空的UITextField按下退格键。 例如,如果您在邮件应用程序中有“冒泡的”收件人,则当您在UITextField退时,它会select最后一个“冒泡的”收件人。

这可以通过与Jacob Caraballo的答案类似的方式来完成。 但在Jacob的回答中,如果UITextField只有一个字符,当你点击backspace时,在收到委托消息的时候, UITextField已经是空的了,所以你最好在一个文本字段上检测最多一个字符的backspace

实际上,如果你想在一个UITextField上检测backspace ,那么你应该在调用super deleteBackward之前把消息发送给delegate 。 例如:

 #import "MyTextField.h" //Text field that detects when backspace is hit with empty text @implementation MyTextField #pragma mark - UIKeyInput protocol -(void)deleteBackward { BOOL isTextFieldEmpty = (self.text.length == 0); if (isTextFieldEmpty) { if ([self.delegate respondsToSelector:@selector(textFieldDidHitBackspaceWithEmptyText:)]) { [self.delegate textFieldDidHitBackspaceWithEmptyText:self]; } } [super deleteBackward]; } @end 

这种文本字段的界面如下所示:

 @protocol MyTextFieldDelegate; @interface MyTextField : UITextField @property(nonatomic, weak) id<MyTextFieldDelegate> delegate; @end @protocol MyTextFieldDelegate <UITextFieldDelegate> @optional -(void)textFieldDidHitBackspaceWithEmptyText:(MyTextField *)textField; @end 

在iOS 6中,当按下退格键时,在UITextField上调用deleteBackward方法,包括字段为空时。 所以你可以inheritanceUITextField并提供你自己的deleteBackward实现(也是调用super的)。

我仍然支持iOS 5,所以我需要结合Andrew的答案和这个。

是的,使用下面的方法来检测退格,当textField是空的。

需要添加UITextFieldDelegate

yourTextField.delegate = self (必须)

迅速:

 func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true } 

目标C:

 - (BOOL)keyboardInputShouldDelete:(UITextField *)textField { return YES; } 

:)只是标题“检测退格”,我使用UIKeyboardTypeNumberPad

我今晚也遇到同样的问题,下面是我的代码找出来的:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSLog([NSString stringWithFormat:@"%d", [string length]]); } 

因为使用UIKeyboardTypeNumberPad ,用户只能inputNumber或Backspace,所以当string长度为0时,必须是退格键。

希望以上会做一些帮助。

而不是尝试预先构build文本字段中的内容,或者找出在shouldChangeCharactersInRange方法中input了什么特殊字符,我会build议您执行以下操作:

 [self performSelector:@selector(manageSearchResultsDisplay) withObject:nil afterDelay:0]; 

这使您可以在当前操作完成后直接调用方法。 这很酷的是,当它完成时,修改后的值将已经在UITextField 。 在这一点上,你可以检查它的长度和/或基于什么在那里validation。

UITextField的子类在iOS 8.3上不适用于我,deleteBackward从来没有被调用过。

以下是我使用的解决scheme,适用于所有iOS 8版本,并且也适用于其他iOS版本

 for textField in textFields { textField.text = " " } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { if string == "" && textField.text == " " { // Do stuff here return false } return true } 

使用TextField委托方法:

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

在上面的方法中添加下面的代码来检测删除事件

 if(textField == YourTextField) { if ([string length] == 0 && range.length > 0) { // Your Code after deletion of character } } 

保持简单这里是唯一的条件你需要检查

  if (range.length==1) 
 + (BOOL)detectBackspaceOnly:(NSString *)string { for(int i=0 ; i<string.length ; i++){ unichar caract = [string characterAtIndex:i]; if(caract != ' ' && caract != '\n') return NO; } return YES; } 

像这样的东西:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (![text hash] && ![textField.text length]) [self backspaceInEmptyTextField]; } 

当然散列是一个string。

UITextViewDelegate

 - (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { if(text isEqualToString:@""); { NSLog(@"press backspace."); } } 

它对我来说没问题。

更新中文简体拼音和中文手写input:

 - (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { if (range.length > 0 && [text isEqualToString:@""]) { NSLog(@"press Backspace."); } return YES; } 

根据文件说:

“如果用户按下deleteKey ,则范围的长度为1,空string对象将replace该单个字符。”