即使UITextField为空,我是否可以检测到删除键?
当UITextField不包含任何内容时,按下键盘的删除键将不会调用任何UITextFieldDelegate的方法。
我如何检测它?
编辑:似乎没有无用的方法来做到这一点。 我能find的最有用的链接是:
-
UITextField:任何方式来检测删除键事件时,该字段为空?
-
如何获得在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]; }