如何创建 OTP 验证屏幕并在多个 uitextfield 上向后检测删除是 Swift
Posted
技术标签:
【中文标题】如何创建 OTP 验证屏幕并在多个 uitextfield 上向后检测删除是 Swift【英文标题】:How to create OTP verification screen and detect delete backward on multiple uitextfield is Swift 【发布时间】:2022-01-03 23:30:21 【问题描述】:所以我做了这个 otp 屏幕,但我有一些问题,
我用一堆 uitextfield 制作这个 otp 屏幕,我制作了它的逻辑,但我无法删除我制作的文本字段中的 num
当我像我的 num 的前 2 个一样填充时,文本字段不会删除,即使我按下 backButton 它也不起作用.....但是当我填充整个文本字段时它会起作用,在我的情况下是六个。
所以我必须填写所有六个数字,我可以从文本字段中删除数字,如果只填写一半,它将无法工作。
这是我的代码:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if ((textField.text?.count)! < 1) && (string.count > 0)
if textField == txtOTP1
txtOTP2.becomeFirstResponder()
if textField == txtOTP2
txtOTP3.becomeFirstResponder()
if textField == txtOTP3
txtOTP4.becomeFirstResponder()
if textField == txtOTP4
txtOTP5.becomeFirstResponder()
if textField == txtOTP5
txtOTP6.becomeFirstResponder()
if textField == txtOTP6
txtOTP6.resignFirstResponder()
textField.text = string
return false
else if ((textField.text?.count)! >= 1) && (string.count == 0)
if textField == txtOTP2
txtOTP1.becomeFirstResponder()
if textField == txtOTP3
txtOTP2.becomeFirstResponder()
if textField == txtOTP4
txtOTP3.becomeFirstResponder()
if textField == txtOTP5
txtOTP4.becomeFirstResponder()
if textField == txtOTP6
txtOTP5.becomeFirstResponder()
if textField == txtOTP1
txtOTP1.resignFirstResponder()
textField.text = ""
return false
else if (textField.text?.count)! >= 1
textField.text = string
return false
return true
这就是我用来制作 otp uitextField 逻辑的代码......请告诉我,我知道我的逻辑有问题,谢谢。
我在此视频中观看了制作此 otp 屏幕的教程 https://www.youtube.com/watch?v=gZnBXh0TRO8根据制造商的说法,他说要解决这个问题,我只需要“将文本字段的用户交互设置为 false 并让第一个文本字段成为第一响应者”,我想我只是这样做了,但我可能做错了.. ..
我真的需要解决这个问题,谢谢。
【问题讨论】:
【参考方案1】:我更愿意创建一个自定义文本字段,而不是修复该代码,以便在按下 deleteBackward 键时发出通知。所以首先继承一个 UITextField:
import UIKit
class SingleDigitField: UITextField
// create a boolean property to hold the deleteBackward info
var pressedDelete = false
// customize the text field as you wish
override func willMove(toSuperview newSuperview: UIView?)
keyboardType = .numberPad
textAlignment = .center
backgroundColor = .blue
isSecureTextEntry = true
isUserInteractionEnabled = false
// hide cursor
override func caretRect(for position: UITextPosition) -> CGRect .zero
// hide selection
override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] []
// disable copy paste
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool false
// override deleteBackward method, set the property value to true and send an action for editingChanged
override func deleteBackward()
pressedDelete = true
sendActions(for: .editingChanged)
现在在您的 ViewCONtroller 中:
import UIKit
class ViewController: UIViewController
// connect the textfields outlets
@IBOutlet weak var firstDigitField: SingleDigitField!
@IBOutlet weak var secondDigitField: SingleDigitField!
@IBOutlet weak var thirdDigitField: SingleDigitField!
@IBOutlet weak var fourthDigitField: SingleDigitField!
override func viewDidLoad()
super.viewDidLoad()
// add a target for editing changed for each field
[firstDigitField,secondDigitField,thirdDigitField,fourthDigitField].forEach
$0?.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
// make the firsDigitField the first responder
firstDigitField.isUserInteractionEnabled = true
firstDigitField.becomeFirstResponder()
// here you control what happens to each change that occurs to the fields
@objc func editingChanged(_ textField: SingleDigitField)
// check if the deleteBackwards key was pressed
if textField.pressedDelete
// reset its state
textField.pressedDelete = false
// if the field has text empty its content
if textField.hasText
textField.text = ""
else
// otherwise switch the field, resign the first responder and activate the previous field and empty its contents
switch textField
case secondDigitField, thirdDigitField, fourthDigitField:
textField.resignFirstResponder()
textField.isUserInteractionEnabled = false
switch textField
case secondDigitField:
firstDigitField.isUserInteractionEnabled = true
firstDigitField.becomeFirstResponder()
firstDigitField.text = ""
case thirdDigitField:
secondDigitField.isUserInteractionEnabled = true
secondDigitField.becomeFirstResponder()
secondDigitField.text = ""
case fourthDigitField:
thirdDigitField.isUserInteractionEnabled = true
thirdDigitField.becomeFirstResponder()
thirdDigitField.text = ""
default:
break
default: break
// make sure there is only one character and it is a number otherwise delete its contents
guard textField.text?.count == 1, textField.text?.last?.isWholeNumber == true else
textField.text = ""
return
// switch the textField, resign the first responder and make the next field active
switch textField
case firstDigitField, secondDigitField, thirdDigitField:
textField.resignFirstResponder()
textField.isUserInteractionEnabled = false
switch textField
case firstDigitField:
secondDigitField.isUserInteractionEnabled = true
secondDigitField.becomeFirstResponder()
case secondDigitField:
thirdDigitField.isUserInteractionEnabled = true
thirdDigitField.becomeFirstResponder()
case thirdDigitField:
fourthDigitField.isUserInteractionEnabled = true
fourthDigitField.becomeFirstResponder()
default: break
case fourthDigitField:
fourthDigitField.resignFirstResponder()
default: break
Xcode 12 sample project
【讨论】:
以上是关于如何创建 OTP 验证屏幕并在多个 uitextfield 上向后检测删除是 Swift的主要内容,如果未能解决你的问题,请参考以下文章
在让用户使用pyotp创建新密码之前如何实现基于OTP的验证?
如何使用 Firebase android 验证收到的用于手机号码验证的 OTP