【问题标题】:How to recognize phone number autofill input in shouldCharactersChangeIn (UITextField)如何在 shouldCharactersChangeIn (UITextField) 中识别电话号码自动填充输入
【发布时间】:2020-08-17 10:05:34
【问题描述】:

所以我编写了自己的自定义电话号码格式化程序(用于 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 中没有显示任何内容。就像我按下了完全没有任何作用的键。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    当自动填充发生时,委托方法确实没有被调用。

    由于UITextFieldUIControl的子类,你可以监听控制事件。

    UITextField 发送.editingChanged 控制事件,用于从键盘输入和自动填充。

    像这样添加你的事件监听器:

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

    然后,实现func editingChanged(_ sender: UITextField) 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      • 2011-03-27
      • 2010-11-17
      • 2021-08-20
      • 2021-11-05
      相关资源
      最近更新 更多