检测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该单个字符。”