How to add separator after every 2 character while

2020-04-21 03:13发布

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.

5条回答
淡お忘
2楼-- · 2020-04-21 03:45

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.

查看更多
Fickle 薄情
3楼-- · 2020-04-21 03:46

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
}
查看更多
不美不萌又怎样
4楼-- · 2020-04-21 03:47

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.

查看更多
虎瘦雄心在
5楼-- · 2020-04-21 03:49

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
    }
}
查看更多
爱情/是我丢掉的垃圾
6楼-- · 2020-04-21 03:58

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:".

查看更多
登录 后发表回答