斯威夫特 4
灵感来自@Anurag Soni 和@Varun Naharia 答案
变体 A
extension EnterConfirmationCodeTextField: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let textFieldCount = textField.text?.count else { return false }
// Сlosure
let setValueAndMoveForward = {
textField.text = string
let nextTag = textField.tag + 1
if let nextResponder = textField.superview?.viewWithTag(nextTag) {
nextResponder.becomeFirstResponder()
}
}
// Сlosure
let clearValueAndMoveBack = {
textField.text = ""
let previousTag = textField.tag - 1
if let previousResponder = textField.superview?.viewWithTag(previousTag) {
previousResponder.becomeFirstResponder()
}
}
if textFieldCount < 1 && string.count > 0 {
setValueAndMoveForward()
if textField.tag == 4 {
print("Do something")
}
return false
} else if textFieldCount >= 1 && string.count == 0 {
clearValueAndMoveBack()
return false
} else if textFieldCount >= 1 && string.count > 0 {
let nextTag = self.tag + 1
if let previousResponder = self.superview?.viewWithTag(nextTag) {
previousResponder.becomeFirstResponder()
if let activeTextField = previousResponder as? UITextField {
activeTextField.text = string
}
}
return false
}
return true
}
}
变体 B(有点另一种行为):
extension EnterConfirmationCodeTextField: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let textFieldCount = textField.text?.count else { return false }
// Сlosure
let setValueAndMoveForward = {
textField.text = string
let nextTag = textField.tag + 1
if let nextResponder = textField.superview?.viewWithTag(nextTag) {
nextResponder.becomeFirstResponder()
}
}
// Сlosure
let clearValueAndMoveBack = {
textField.text = ""
let previousTag = textField.tag - 1
if let previousResponder = textField.superview?.viewWithTag(previousTag) {
previousResponder.becomeFirstResponder()
}
}
if textFieldCount < 1 && string.count > 0 {
setValueAndMoveForward()
if textField.tag == 4 {
print("Do something")
}
return false
} else if textFieldCount >= 1 && string.count == 0 {
clearValueAndMoveBack()
return false
} else if textFieldCount >= 1 {
setValueAndMoveForward()
return false
}
return true
}
}
另外,我实现了这个功能:
在最后一个textFiled为空的情况下,我只想切换到上一个textFiled。我尝试了所有这些方法。但对我来说,下面的方法更优雅,而且很有魅力:
变体 A
class EnterConfirmationCodeTextField: UITextField {
// MARK: Life cycle
override func awakeFromNib() {
super.awakeFromNib()
delegate = self
}
// MARK: Methods
override func deleteBackward() {
super.deleteBackward()
let previousTag = self.tag - 1
if let previousResponder = self.superview?.viewWithTag(previousTag) {
previousResponder.becomeFirstResponder()
if let activeTextField = previousResponder as? UITextField {
if let isEmpty = activeTextField.text?.isEmpty, !isEmpty {
activeTextField.text = String()
}
}
}
}
}
变体 B(有点另一种行为):
class EnterConfirmationCodeTextField: UITextField {
// MARK: Life cycle
override func awakeFromNib() {
super.awakeFromNib()
delegate = self
}
// MARK: Methods
override func deleteBackward() {
super.deleteBackward()
let previousTag = self.tag - 1
if let previousResponder = self.superview?.viewWithTag(previousTag) {
previousResponder.becomeFirstResponder()
}
}
}
EnterConfirmationCodeTextField
为每个文本字段分配并设置它们适当的tag
值。