所以我编写了自己的自定义电话号码格式化程序(用于UITextField(。问题是,我在函数shouldCharactersChangeIn中调用它,由于某种原因,它在使用自动填充时无法检测到任何正在填充的字符。这是我的电话号码格式化程序的代码:
extension UITextField {
func phoneNumberValidation(shouldChangeCharactersIn range: NSRange, replacementString string: String, phoneNumber: String = "(XXX) XXX-XXXX", replacementCharacter: Character = "X") {
// phoneNumber should have base replacement character X (you can customize it
let maxLength = phoneNumber.count
if maxLength == 0 {
return
}
var currentPosition = 0
if let selectedRange = self.selectedTextRange {
currentPosition = self.offset(from: self.beginningOfDocument, to: selectedRange.start)
}
var restrictedString = string
if string.count > 0 {
let disallowedCharacterSet = NSCharacterSet(charactersIn: " 0123456789-()").inverted
if string.rangeOfCharacter(from: disallowedCharacterSet) != nil {
restrictedString = ""
currentPosition -= 1
}
}
var removeCharactersAt: [[Any]] = []
let charSet = CharacterSet(charactersIn: String(replacementCharacter))
var removeText = phoneNumber.trimmingCharacters(in: charSet)
removeText = removeText.components(separatedBy: charSet).joined()
for i in 0..<removeText.count {
let text = phoneNumber
let range: Range<String.Index> = text.range(of: String(removeText.charAt(i)))!
let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)
removeCharactersAt.append([removeText.charAt(i), index])
}
var tempRemoveArray = [Int]()
for i in 0..<(removeCharactersAt.count - 1) {
if (removeCharactersAt[i][1] as! Int + 1) == removeCharactersAt[i+1][1] as! Int {
let newString: String = String(removeCharactersAt[i][0] as! Character)
let newString1: String = String(removeCharactersAt[i + 1][0] as! Character)
removeCharactersAt[i][0] = newString + newString1
tempRemoveArray.append(i + 1)
}
}
for i in 0..<tempRemoveArray.count {
removeCharactersAt.remove(at: tempRemoveArray[i])
}
var currentText = NSString(string: self.text!).replacingCharacters(in: range, with: restrictedString)
print(currentText)
for i in 0..<removeText.count {
let character: String = String(removeText.charAt(i))
let charset = CharacterSet(charactersIn: character)
if currentText.rangeOfCharacter(from: charset) != nil {
currentPosition -= 1
}
}
let delCharSet = CharacterSet(charactersIn: removeText)
currentText = currentText.trimmingCharacters(in: delCharSet)
currentText = currentText.components(separatedBy: delCharSet).joined()
for i in 0..<removeCharactersAt.count {
let index: Int = removeCharactersAt[i][1] as! Int
let replacementCharactertemp = removeCharactersAt[i][0]
var replacementCharacter: String
var replacementTemp = replacementCharactertemp as? String
if replacementTemp == nil {
replacementTemp = String(replacementCharactertemp as! Character)
}
if replacementTemp!.count > 1 {
replacementCharacter = String(replacementCharactertemp as! String)
} else {
replacementCharacter = String(replacementCharactertemp as! Character)
}
if currentText.count > index {
if !(range.length == 1 && range.location == (index + replacementCharacter.count) && currentText.count < (index + replacementCharacter.count)) {
for i in 0..<replacementCharacter.count {
currentText.insert(replacementCharacter.charAt(i), at: currentText.index(currentText.startIndex, offsetBy: index + i))
currentPosition += 1
}
}
for i in 0..<replacementCharacter.count {
if range.location == (index + i) && range.length == 1 {
currentPosition -= 1
}
}
}
}
for i in 0..<removeCharactersAt.count {
let index: Int = removeCharactersAt[i][1] as! Int
let replacementCharactertemp = removeCharactersAt[i][0]
var replacementCharacter: String
var replacementTemp = replacementCharactertemp as? String
if replacementTemp == nil {
replacementTemp = String(replacementCharactertemp as! Character)
}
if replacementTemp!.count > 1 {
replacementCharacter = String(replacementCharactertemp as! String)
} else {
replacementCharacter = String(replacementCharactertemp as! Character)
}
if range.location == index && currentText.count > (index + replacementCharacter.count) && range.length != 1{
currentPosition += 1
}
}
if currentText.count > maxLength {
currentText = String(currentText.prefix(maxLength))
}
if(string == ""){
currentPosition = currentPosition - 1
} else {
currentPosition = currentPosition + 1
}
self.text = currentText
if let newPosition = self.position(from: self.beginningOfDocument, offset: currentPosition) {
print(newPosition)
self.selectedTextRange = self.textRange(from: newPosition, to: newPosition)
}
}
}
我是这样称呼它的:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.tag == 4 || textField.tag == 5 || textField.tag == 6 {
var phoneNumber = ""
if countryId == 1 {
phoneNumber = "XXXX-XXXXXX"
} else if countryId == 2 {
phoneNumber = "(XXX) XXX-XXXX"
} else {
phoneNumber = ""
(textField as! FloatingLabel).displayErrorMessage(message: "Please select a country first")
}
print(textField)
print(range)
print(string)
textField.phoneNumberValidation(shouldChangeCharactersIn: range, replacementString: string, phoneNumber: phoneNumber)
}
return false
}
当用户自动填充时,我如何检测正在填充的字符。目前,自动填充不起任何作用,文本字段保持空白。我尝试打印textField、字符串和范围,但当我按下自动填充选项卡时,字符串、范围或textField中没有显示任何内容。就好像我按下了键,却什么也没做。
当发生自动填充时,委托方法确实不会被调用。
由于UITextField
是UIControl
的子类,因此可以侦听控制事件。
UITextField
发送.editingChanged
控制事件,用于键盘打字和自动填充。
像这样添加您的事件侦听器:
textField.addTarget(self, action: #selector(editingChanged(_:)), for: .editingChanged)
然后,实现了func editingChanged(_ sender: UITextField)
方法。