In my project I need to put device MAC address validation while adding text in text field. My device mac address format is “AB:5E:CF:45:S5:6D”. So when ever I will add any character it should be changed with adding colon after 2 character in textfield.
Example : “45DF5R6” = “45:DF:5R:6” “SD45ER65DF6G” = “SD:45:ER:65:DF:6G”
Appreciated your help.
Thanks in advance.
You're looking for delegate function of a UITextField:
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool
You can write input specific logic in that function. It often used for masking phone numbers, or say limiting number of characters added to a textfield. Your formatting issue also fits great.
In delegate method of UITextField
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool
Add a logic that will check length MOD 2 of the string excluding the character you want to insert. If you get remainder equal to 0, add the desired character to the string.
Here is another answer for you. You have to implement the UITextFieldDelegate and set the textField delegate as self. Then implement the below delegate method.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text, let textRange = Range(range, in: text) else {
return false
}
var updatedText = text.replacingCharacters(in: textRange, with: string)
updatedText.removeAll(where: {$0 == ":"})
let finalLength = updatedText.count + updatedText.count/2 - 1
if finalLength > 17 {
return false
}
for i in stride(from: 2, to: finalLength, by: 3) {
let index = updatedText.index(updatedText.startIndex, offsetBy: i)
updatedText.insert(":", at: index)
}
textField.text = updatedText
return false
}
The logic here is really easy to understand:
- Strip the string of all the ":" which you may have inserted last time.
- Insert the ":" at every 3rd position in the string and set the string manually in
shouldChangeCharacters
You should include other logic like character limit, character restrictions, copy-paste handling yourself. The answer just focusses on the logic involved in adding and removing “:”
You do not have to delete the ":" that is inserted when deleting characters. eg: If you have "45:D" and you press delete once, you will be left with "45" and not "45:".
You should subclass UITextField and add a target for editing changed control event, then you just need to remove the invalid hexa characters and format the cleaned string again using the method to insert a character every two characters in a string as I posted in this answer:
class MacAddressField: UITextField {
override func didMoveToSuperview() {
keyboardType = .default
textAlignment = .left
autocorrectionType = .no
autocapitalizationType = .none
addTarget(self, action: #selector(editingChanged), for: .editingChanged)
}
@objc func editingChanged(_ textField: UITextField) {
text!.removeAll { !(("A"..."F") ~= $0) &&
!(("a"..."f") ~= $0) &&
!(("0"..."9") ~= $0) } // remove non hexa string characters
text! = String(text!.lowercased().prefix(12)) // get the up to 12 characters lowercased
.pairs.joined(separator: ":") // and format it again
}
}
extension String {
var pairs: [String] {
var result: [String] = []
let characters = Array(self)
stride(from: 0, to: count, by: 2).forEach {
result.append(String(characters[$0..<min($0+2, count)]))
}
return result
}
}
try this
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = (textField.text! as NSString).replacingCharacters(in: range, with: string)
let count = text.count
if string != "" {
if count > 17
{
return false
}
if count % 3 == 0{
txtField.text?.insert(":", at: String.Index.init(encodedOffset: count - 1))
}
return true
}
return true
}
来源:https://stackoverflow.com/questions/52479082/how-to-add-separator-after-every-2-character-while-changing-text-in-textfield-in