即使UITextField为空,我是否可以检测到删除键?

当UITextField不包含任何内容时,按下键盘的删除键将不会调用任何UITextFieldDelegate的方法。

我如何检测它?

编辑:似乎没有无用的方法来做到这一点。 我能find的最有用的链接是:

  1. UITextField:任何方式来检测删除键事件时,该字段为空?

  2. 如何获得在UITextField中按下的实际按键

总之,我的解决scheme是在文本字段的开始部分放置一个永久的空格。 并进行其他必要的更改(textFieldShouldReturn:,textField:shouldChangeCharactersInRange:replacementString:等)。

它可能会把一个button,但这是有点脆弱,因为键盘布局可能会改变与不同的iOS版本,不同的语言当然有不同的键盘布局。

看看“pipe理文本字段和文本视图”苹果文档。 我确定有办法做到这一点。 它像一个UITextField实现一个协议来获取keyevents。 其中一个关键事件可能是一个删除键,所以你可以重写任何方法接收这些,并得到它的方式。

这似乎可以通过inheritanceUITextField。 UITextField符合名为UITextInput的协议,该协议符合另一个名为UIKeyInput的协议。 UIKeyInput协议有一个方法deleteBackward,每次键盘上的退格键被按下时触发。

这是它的外观

 #import <UIKit/UIKit.h> @interface EmptyDeleteTextField : UITextField @end 

履行

 - (void)deleteBackward { NSLog_SM(@"Length: %d", (int)self.text.length); [super deleteBackward]; } 

PS:不要忘记调用超级,因为你不想混淆UITextField的默认行为。

好的,我明白了。 所以在- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text委托方法(即当文本即将被input),你只需做一个

 if (text.length <= 0) { // backspace return FALSE; } else { 

因为对于退格text.length将== 0,其他一切将== 1。

这可以通过inheritanceUITextField并将其添加为所需文本字段的自定义类来实现。 然后重写方法“deleteBackward”这个方法将捕获所有的退格事件。

Swift中的代码:

 override func deleteBackward() { super.deleteBackward() // Enter your stuff here } 

还要确保你也在调用超级方法,因为它正在执行事件的基本function。

把一个不可见的button放在上面。

我不知道,但你可以尝试使用addTarget: action: forControlEvents:的自定义方法addTarget: action: forControlEvents: 试试UIControlEventAllEditingEvents选项。

我在swift 3中添加了一个更完整的例子。基本上,我需要pincodetypes的视图,其中有多个文本字段,允许每个单元格中的一个字符。

喜欢这个 在这里输入图像说明 我开始创build一个UITextField的子类和一个定义一个新的func的协议。

 protocol MYDeleteActionTextFieldDelegate { func textFieldDidSelectDeleteButton(_ textField: UITextField) -> Void } class MYDeleteActionTextField: UITextField { var deleteDelegate: MYDeleteActionTextFieldDelegate? override func deleteBackward() { // Need to call this before super or the textfield edit may already be in place self.deleteDelegate?.textFieldDidSelectDeleteButton(self) super.deleteBackward() } } 

然后你用新的子类创build文本字段,并在视图控制器中实现委托。 就我而言,我pipe理数组中的文本字段以便于使用,并使用PureLayout来布局单元格。 我像这样储存它们

var pinFields = UITextField

然后在viewDidLoad() ,我将所有的引脚字段添加到数组中,如下所示:

 for _ in 1...6 { let field = EDFDeleteActionTextField.init(forAutoLayout: ()) field.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControlEvents.editingChanged) field.delegate = self field.deleteDelegate = self field.textAlignment = .center field.font = UIFont.newBigTitle() field.textColor = UIColor.edfBlue() field.backgroundColor = UIColor.edfWhite() self.pinFields.append(field) self.pinView.addSubview(field) } 

现在你只需要响应上面添加的所有合适的委托方法和textFieldDidChange目标。

 // MARK: UITextFieldDelegate func textFieldDidChange(textField: UITextField) { // If the user typed one character, move to the next cell. if (textField.text?.characters.count == 1) { let index = pinFields.index(of: textField) textField.resignFirstResponder() if (pinFields.count > index! + 1) { pinFields[index! + 1].becomeFirstResponder() } } // If they deleted the character move to previous cell else if (textField.text?.characters.count == 0) { let index = pinFields.index(of: textField) if (index! - 1 >= 0) { pinFields[index! - 1].becomeFirstResponder() } } } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if range.location > 0 { let index = pinFields.index(of: textField) // If there is already text in the text field and the next cell is empty - move the newly typed character to that cell. if (pinFields.count > index! + 1) { let nextField = pinFields[index! + 1] if (nextField.text?.characters.count == 0) { textField.resignFirstResponder() nextField.becomeFirstResponder() nextField.text = string } } return false } return true } func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return false } // MARK: EDFDeleteActionTextFieldDelegate func textFieldDidSelectDeleteButton(_ textField: UITextField) { // If user clicked delete, and there are no characters, move to previous cell if available. // If there are characters, it is handled in UITextFieldDelegate if (textField.text?.characters.count == 0) { let index = pinFields.index(of: textField) if (index! - 1 >= 0) { pinFields[index! - 1].becomeFirstResponder() } else { textField.resignFirstResponder() } } } 

我会省去那些无聊的部分(比如布置文本字段等),因为这个通用function在这个pincode视图比较多的情况下是有用的,但是实现这个子类和协议应该提供类似types所需的所有function意见和解决手头的问题(这可能需要类似的东西)。

快乐的编码。

当使用小键盘时,显然你正在写一些variables(例如:UITextField,UILabel甚至全局string)

检测删除操作的选项可以是:

  • 保持全局“int previousLengthOfText”
  • 初始化这个var为lastLengthOfText = 0;
  • 赶上委托function的变化:例如:

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

  • 比较你的标签\ textField到这个全局variables的长度,看看是否添加或删除了一个字符。

例如:

 if ([self.myTextField.text length] > previousLengthOfText) { { // user deleted a character - Do your action here previousLengthOfText = [self.myTextField.text length]; }