【问题标题】:Auto hidden keyboard after enter six characters输入六个字符后自动隐藏键盘
【发布时间】:2018-08-08 05:25:53
【问题描述】:

我是一个快速的初学者。我在 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

【问题讨论】:

  • 能否提供完整的崩溃日志。
  • 您只需要使用TextField委托方法并检查输入的长度是否大于6或者不是退格字符然后不允许将其添加到文本字段。
  • 您不需要任何此代码。只需子类化 viewController 并尝试我发布的答案。
  • @Lal Krishna 和@Rakesha Shastri 的回答真的对我有帮助。我尝试使用委托方法`func textField(_ textField:UITextField,shouldChangeCharactersIn range:NSRange,replacementString string:String)-> Bool {}`来实现这个功能。我认为它很不令人满意。不要忘记用户可以通过手机剪贴板粘贴内容。
  • 如果结果超过 6 个字符,您可以阻止用户的复制粘贴。我已经用这个逻辑更新了我的答案。

标签: ios swift keyboard uitextfielddelegate


【解决方案1】:

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

参考:Link1Link2

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)

【讨论】:

  • 很高兴为您提供帮助。您能否接受此答案,以便将来对其他人有所帮助。
  • 没问题!这是我应该做的。
【解决方案2】:

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

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
    }    
}

【讨论】:

  • OP 显然希望在输入第六个字符后关闭 textField。所以他使用了正确的代表。这是错误的。
  • 正如@RakeshaShastri 所说,我希望在输入第六个字符后解除文本字段。我试试你的代码。Test you code。还有This is I want.
  • @UninhibitedSoul 只需将长度 == 6 更改为 7 即可获得所需的输出。
  • @Rakesh Patel 我不这么认为。想象一下,如果你有一个六位数的验证码,你会在输入验证码后再输入一个数字吗?这是不合理的
  • @UninhibitedSoul 取决于您的要求。我只写了一个代码在文本字段获得 6 个字符后关闭键盘。
【解决方案3】:

您不应该使用字符串文字构造选择器,而应使用#selector(textFieldDidChange(textField:)),然后您将看到选择器方法需要暴露给Objective C。
因此,您应该可以通过编写来修复它:

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

【讨论】:

  • 至于第二个/第三个问题:为什么不为这个功能创建一个子类而不是一个协议?
【解决方案4】:

你必须为此实现一个委托方法:

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

【讨论】:

  • 当用户在第六个字符之后输入第七个字符时,这将关闭键盘。
猜你喜欢
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多