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

Posted

技术标签:

【中文标题】输入六个字符后自动隐藏键盘【英文标题】: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()
    //        
    //    
    //

    为什么我的应用程序崩溃。 EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0) 通过使用选择器#selector(textFieldDidChange(textField:autoHidenLenth:)) 创建一个动作,我不知道如何将第二个参数传递给函数。例如参数 autoHidenLenth。 如何通过协议正确实现该功能?

(来源:recordit.co)

【问题讨论】:

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

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

参考: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)

【讨论】:

很高兴为您提供帮助。您能否接受此答案,以便将来对其他人有所帮助。 没问题!这是我应该做的。【参考方案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

【讨论】:

当用户在第六个字符之后输入第七个字符时,这将关闭键盘。

以上是关于输入六个字符后自动隐藏键盘的主要内容,如果未能解决你的问题,请参考以下文章

react native 隐藏键盘 TextInput失去焦点

appium+java 如何隐藏安卓键盘

SwiftUI实现Textfield输入键盘自动隐藏

appium 隐藏键盘后怎样显示键盘

关于Android平台显示隐藏软键盘输入法的方法总结

关于Android平台显示隐藏软键盘输入法的方法总结