How to add separator after every 2 character while changing text in textfield in Swift 4

可紊 提交于 2019-12-02 04:53:31

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
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!