防止 UITextField 在更改 firstResponder 时取值
Posted
技术标签:
【中文标题】防止 UITextField 在更改 firstResponder 时取值【英文标题】:Prevent UITextField from taking values on changing the firstResponder 【发布时间】:2017-12-12 11:00:06 【问题描述】:我有四个 UITextField,每个都代表 OTP 的一个数字。当用户键入代码时,我希望控件转移到连续的文本字段。我的实现如下。
extension FillSignUpCodeController: UITextFieldDelegate
func textFieldDidBeginEditing(_ textField: UITextField)
textField.text = ""
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
let inputString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
if inputString.count == 1
switch textField
case textFieldCodeFirstDigit:
textFieldCodeFirstDigit.text = inputString
textFieldCodeFirstDigit.resignFirstResponder()
textFieldCodeSecondDigit.becomeFirstResponder()
case textFieldCodeSecondDigit:
textFieldCodeSecondDigit.text = inputString
textFieldCodeSecondDigit.resignFirstResponder()
textFieldCodeThirdDigit.becomeFirstResponder()
case textFieldCodeThirdDigit:
textFieldCodeThirdDigit.text = inputString
textFieldCodeThirdDigit.resignFirstResponder()
textFieldCodeFourthDigit.becomeFirstResponder()
case textFieldCodeFourthDigit:
textFieldCodeFourthDigit.text = inputString
textFieldCodeFourthDigit.resignFirstResponder()
default:
return false
return true
使用这段代码,当用户键入第一个数字时,第一个文本字段将获取输入值并将控件移动到下一个文本字段。但是,第二个文本字段采用第一个数字的值。我尝试在更改 firstResponder 后将文本设置为空,但它不起作用。我该如何解决这个问题?谢谢。
【问题讨论】:
【参考方案1】:由于textField(_:shouldChangeCharactersIn:replacementString:)
执行之前文本出现在文本字段中,您应该将代码放在文本已更改时调用的方法中。
您应该观察文本字段的变化并在那里执行响应者更改代码。您可以找到有关该in this question 的更多信息。
此外,在更改第一响应者之前将其辞职是多余的,您无需这样做。
单独处理每个文本字段也是非常多余的。我建议将您的文本字段包含在一个数组中并遍历它们。
【讨论】:
【参考方案2】:shouldChangeCharactersInRange 在填充 textField 之前被调用。你可以这样做:
textField.addTarget(self, action: #selector(textFieldChangedValue(textField:)), for: UIControlEvents.editingChanged)
为 viewDidLoad() 中的所有文本字段写上一行
@objc func textFieldChangedValue(textField: UITextField)
print(textField.text)
这会起作用
【讨论】:
【参考方案3】:根据@the4kman 和@Rahul Dasgupta 的回答,我实现了以下内容:
FillUpCodeViewController.swift
override func viewDidLoad()
setupArrrayofTextFields(textField1: textFieldCodeFirstDigit,
textField2: textFieldCodeSecondDigit,
textField3: textFieldCodeThirdDigit,
textField4: textFieldCodeFourthDigit)
func setupArrrayofTextFields(textField1: UITextField, textField2: UITextField,
textField3: UITextField, textField4: UITextField)
arrayOftextFields = [textField1, textField2, textField3, textField4]
for textField in arrayOftextFields
textField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
@objc func textFieldDidChange(textField: UITextField)
guard textField.text?.count == 0 else
let index: Int = arrayOftextFields.index(of: textField)!
guard index == (arrayOftextFields.count-1) else
arrayOftextFields[index+1].becomeFirstResponder()
return
textField.resignFirstResponder()
return
而且,在我必须实现恢复代码提交的视图控制器中,我只是简单地继承了 FillUpCodeViewController 类。
RecoveryViewController.swift
override func viewDidLoad()
setupArrrayofTextFields(textField1: textFieldRecoveyCodeFirstDigit,
textField2: textFieldRecoveyCodeSecondDigit,
textField3: textFieldRecoveyCodeThirdDigit,
textField4: textFieldRecoveyCodeFourthDigit)
【讨论】:
以上是关于防止 UITextField 在更改 firstResponder 时取值的主要内容,如果未能解决你的问题,请参考以下文章