输入六个字符后自动隐藏键盘

Auto hidden keyboard after enter six characters

我是 swift 初学者。我在 ViewController 中实现了这个功能,但我不想在每个 ViewController 中都写这样的代码。我想通过一个协议来实现它,但是出了点问题。

import UIKit

@objc protocol TextFieldAutoHiddenKeyboard: class {
    var textFieldAutoHidenLenth: UInt {get set} 
}

extension TextFieldAutoHiddenKeyboard where Self: UIViewController {

    func autoHiddenKeyboardWhenFillUpTextFiled(textField textF: UITextField, autoHidenLenth: UInt) {
        textFieldAutoHidenLenth = autoHidenLenth

        let textFieldDidChangeActionName = "textFieldDidChange(textField:)"
        let textFieldDidChangeAction = Selector(textFieldDidChangeActionName)
        textF.addTarget(self, action: textFieldDidChangeAction, for: .editingChanged)

        let dismissKeyboardActionName = "dismissKeyboard"
        let dismissKeyboardAction = Selector(dismissKeyboardActionName)
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: dismissKeyboardAction)
        view.addGestureRecognizer(tap)
      //textF.addTarget(self, action: #selector(textFieldDidChange(textField:autoHidenLenth:)), for: .editingChanged)
    }

    func textFieldDidChange(textField: UITextField) {
        if let text = textField.text {
            if text.count == textFieldAutoHidenLenth {
                textField.resignFirstResponder()
            }
        }
    }

    func dismissKeyboard() {
        view.endEditing(true)
    }

    //@objc func textFieldDidChange(textField: UITextField, autoHidenLenth: UInt) {
    //    if let text = textField.text {
    //        if text.count == autoHidenLenth {
    //           textField.resignFirstResponder()
    //        }
    //    }
    //}
}
  1. 为什么我的应用程序崩溃了。 EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)
  2. 通过使用选择器创建动作,#selector(textFieldDidChange(textField:autoHidenLenth:)),我不知道如何将第二个参数传递给函数。比如参数autoHidenLenth.
  3. 如何通过协议正确实现这个功能?


(来源:recordit.co

您必须为此实现委托方法:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
         let  char = string.cString(using: String.Encoding.utf8)!
    let isBackSpace = strcmp(char, "\b")

    if (isBackSpace == -92) {
        print("Backspace was pressed")
        return true
    }
    if((textField.text?.length)! == 6){
        self.view.endEditing(true)
        return true
    }
    return true
    }

并且不要忘记分配委托

textfield.delegate = self

您使用了错误的文本字段委托。您应该使用文本字段的委托,它响应字符的变化而不是字段的变化。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let length = (yourtextfield.text?.characters.count)! - range.length + string.characters.count
    if length == 6 {

       yourtextfield.resignFirstResponder()
        return true

    }else {
        return true
    }    
}

您不应该使用字符串文字构造选择器,而应该使用 #selector(textFieldDidChange(textField:)),然后您会看到需要向 Objective C.
公开一个选择器方法 因此,您应该可以通过以下方式修复它:

@objc func textFieldDidChange(textField: UITextField) {
    if let text = textField.text {
        if text.count == textFieldAutoHidenLenth {
            textField.resignFirstResponder()
        }
    }
}

由于您需要为多个文本字段启用此功能,您可以使用它。

参考文献:Link1, Link2

private var autoHiddenLengthAssociationKey: UInt8 = 0

extension UITextField {

    private var autoHiddenLenth: Int? {
        get {
            return objc_getAssociatedObject(self, &autoHiddenLengthAssociationKey) as? Int
        }
        set {
            objc_setAssociatedObject(self, &autoHiddenLengthAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
        }
    }

    func enableAutoHidingFeature(maxLength: Int) {
        autoHiddenLenth = maxLength
        self.addTarget(self, action: #selector(textDidChange(textField:)), for: .editingChanged)
    }

    @objc func textDidChange(textField: UITextField) {

        guard let maxLength = autoHiddenLenth, let text = textField.text else { return }

        if text.count == maxLength {
            textField.resignFirstResponder()
        }
    }
}

您可以通过调用以下方式启用此功能:

textField.enableAutoHidingFeature(maxLength: 6)