IOS – 在 Swift 中处理 OnetimeCode

Posted

技术标签:

【中文标题】IOS – 在 Swift 中处理 OnetimeCode【英文标题】:IOS – Handle OnetimeCode in Swift 【发布时间】:2019-11-03 22:35:41 【问题描述】:

有没有办法通过限制其他键盘输入来处理一次性代码点击?

我需要一个 OTP 文本字段来预填充短信 OTP 代码。 用户不应使用键盘数字按钮手动输入 OTP。

ios 12 我们有一次性代码选项,它将自动填充到 QuickType 栏中,用户可以点击它来填充文本字段。我找不到限制其他键盘输入的选项。

有什么方法可以只允许一次性代码点击并限制从数字键盘输入任何内容。

我尝试的是创建 6 个文本字段。 第一个文本字段内容类型设置为一次性代码。 UserInteractionEnabled 仅适用于第一个文本字段,因此用户无法在其他字段中输入数据。 一旦我得到 OTP 并点击 QuickType 栏 - 一次性代码,我将预填充所有文本字段。

viewdidload>

otp1TB.addTarget(self, action:#selector(textFieldDidChange(_:)), for: .editingChanged)


@objc func textFieldDidChange(_ textField: UITextField) 
    if let otpCode = textField.text ,  otpCode.count > 5 
        otp1TB.text = String(otpCode[otpCode.startIndex])
        otp2TB.text = String(otpCode[otpCode.index(otpCode.startIndex, offsetBy: 1)])
        otp3TB.text = String(otpCode[otpCode.index(otpCode.startIndex, offsetBy: 2)])
        otp4TB.text = String(otpCode[otpCode.index(otpCode.startIndex, offsetBy: 3)])
        otp5TB.text = String(otpCode[otpCode.index(otpCode.startIndex, offsetBy: 4)])
        otp6TB.text = String(otpCode[otpCode.index(otpCode.startIndex, offsetBy: 5)])
        otp1TB.isUserInteractionEnabled = false 
        self.view.endEditing(true)
    

这里的问题是,当键盘打开时,第一个文本字段处于活动状态,用户可以从键盘输入数字数据。

我只需要在键盘打开时允许一次代码点击。

【问题讨论】:

你能分享一些你迄今为止尝试过的代码吗? 【参考方案1】:

我认为您可以跳过这整个复杂性,只使用标准的 iOS 12 OTP 输入类型:

otpTextField.textContentType = .oneTimeCode

见:Automatic OTP verification in iOS?

以及涵盖它的 WWDC 2018 视频:https://developer.apple.com/videos/play/wwdc2018/204

【讨论】:

情节提要中第一个文本字段内容类型设置为一次性代码。我正在寻找限制其他键盘数字输入的解决方案。 对不起,你的问题不是很清楚 - 很难理解。听起来你想要这个:***.com/a/53414345/1214800 我试过了。声明“如果 textField.textContentType == UITextContentType.oneTimeCode”没有运气 好的,那么我建议您改写您的问题以明确您遇到的问题,并解释它与您显示的代码的关系。 对不起,如果不清楚。我已经更新了文字【参考方案2】:

你可以试试我的 3rd 方库:- https://github.com/Datt1994/DPOTPView

解决方案:-

在 viewDidLoad 添加标签和委托给所有textfield

override func viewDidLoad() 
    super.viewDidLoad()
    otp1TB.delegate = self
    otp1TB.tag = 1000
    otp2TB.delegate = self
    otp2TB.tag = 2000
    otp3TB.delegate = self
    otp3TB.tag = 3000
    otp4TB.delegate = self
    otp4TB.tag = 4000
    otp5TB.delegate = self
    otp5TB.tag = 5000
    otp6TB.delegate = self
    otp6TB.tag = 6000

在 UITextFieldDelegate 扩展中实现shouldChangeCharactersIn 函数,如下所示,它也适用于textField.textContentType = .oneTimeCode

extension ViewController : UITextFieldDelegate  

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 
    if string.trimmingCharacters(in: CharacterSet.whitespaces).count != 0 
        textField.text = string
        if textField.tag < count*1000 
            let next = textField.superview?.viewWithTag((textField.tag/1000 + 1)*1000)
            next?.becomeFirstResponder()
         else if textField.tag == count*1000 
            textField.resignFirstResponder()
        
     else if string.count == 0  // is backspace
        textField.text = ""
    

    return false



【讨论】:

以上是关于IOS – 在 Swift 中处理 OnetimeCode的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS Swift 中使用键盘平移手势处理文本输入视图移动

如何在 IOS Swift 中使用 SQLite 使用 FMDB 处理多个线程

如何使用动态视图 iOS Swift 处理导航?

Swift 中是不是有 API 来确定 iOS 设备的处理器寄存器大小?

iOS开发-Swift进阶之反射Mirror & 错误处理!

swift_dynamiccast 处理过多并影响 iOS 中的性能