问题
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.
回答1:
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.
回答2:
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.
回答3:
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:".
回答4:
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
}
}
回答5:
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