即使UITextField为空,我还能检测到删除键吗?

yeh*_*nan 15 iphone uitextfield ios

当UITextField什么都不包含时,按下键盘的删除键不会调用任何UITextFieldDelegate的方法.

我该如何检测它?

编辑:似乎没有简单的方法来做到这一点.我能找到的最有用的链接是:

  1. UITextField:当字段为空时,有何方法检测Delete键事件?

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

简而言之,我的解决方案是在文本字段的开头放置一个永久的SPACE.并进行其他nesessary更改(textFieldShouldReturn:,textField:shouldChangeCharactersInRange:replacementString:,等).

Say*_*ain 8

这似乎可以通过继承UITextField来实现.UITextField符合名为UITextInput的协议,该协议符合另一个名为UIKeyInput的协议.UIKeyInput协议有一个方法deleteBackward,每次按下键盘上的退格键时都会触发该方法.

这是它的外观

#import <UIKit/UIKit.h>

@interface EmptyDeleteTextField : UITextField

@end
Run Code Online (Sandbox Code Playgroud)

履行

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

PS:不要忘记调用super,因为你不想搞乱UITextField的默认行为.


小智 8

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

Swift 中的代码:

override func deleteBackward() {
        super.deleteBackward()
        // Enter your stuff here
    }
Run Code Online (Sandbox Code Playgroud)

还要确保您也在调用 super 方法,因为它正在执行事件的基本功能。


joh*_*chd 6

我将这个答案添加为Swift 3中更完整的示例。基本上,我需要一个pincode类型视图,其中有多个文本字段,每个文本字段允许一个字符。

像这样 在此处输入图片说明 我首先创建UITextField的子类和定义新功能的协议。

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,使用新的子类创建文本字段,并在视图控制器中实现委托。就我而言,我管理数组中的文本字段以便于使用,并使用PureLayout对单元进行布局。我这样存放

var pinFields = UITextField

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

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)
        }
Run Code Online (Sandbox Code Playgroud)

现在,您只需要响应所有适当的委托方法和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()
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我将省去一些无聊的部分(例如布置文本字段等),因为这种通用功能比此pincode视图在更多情况下有用,但是实现此子类和协议应该提供类似类型所需的所有功能。查看并解决眼前的问题(可能需要类似的内容)。

快乐的编码。


Dav*_*idN 1

可以在上面放一个按钮,但这有点脆弱,因为键盘布局可能会随着不同的 iOS 版本而改变,而且不同的语言肯定有不同的键盘布局。

请参阅“管理文本字段和文本视图”Apple 文档。我确信有办法做到这一点。它类似于 UITextField 实现一个协议来获取按键事件。这些关键事件之一可能是删除键,因此您可以覆盖接收这些事件的任何方法并以这种方式获取它。