2

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.

Viral Mithani
  • 313
  • 4
  • 17
  • 1
    You surely tried *something.* Don't hesitate to show your attempt, so that it does not look like a “write the code for me” question! – Martin R Sep 24 '18 at 12:11
  • question: Fetching MAC address of an iOS device is not supported since iOS 7. how did you manage to get the address? – Sahil Manchanda Sep 24 '18 at 12:13
  • 3
    Welcome to Stack Overflow! You seem to be asking for someone to write some code for you. Stack Overflow is a question and answer site, not a code-writing service. Please [see here](http://stackoverflow.com/help/how-to-ask) to learn how to write effective questions. – ielyamani Sep 24 '18 at 12:20
  • Note that macaddress string only have hexa characters "0"..."9" and "a"..."f". G, R and S characters are not valid and shouldn't be allowed in your text field – Leo Dabus Sep 24 '18 at 18:08

5 Answers5

2

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
}
Devil Decoder
  • 966
  • 1
  • 10
  • 26
2

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 = text!
            .filter(\.isHexDigit)
            .prefix(12)
            .pairs
            .joined(separator: ":")
            .lowercased()
    }
}

extension Collection {
    func subSequences(limitedTo maxLength: Int) -> [SubSequence] {
        precondition(maxLength > 0, "groups must be greater than zero")
        return .init(sequence(state: startIndex) { start in
            guard start < self.endIndex else { return nil }
            let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex
            defer { start = end }
            return self[start..<end]
        })
    }
    var pairs: [SubSequence] { subSequences(limitedTo: 2) }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
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.

inokey
  • 5,434
  • 4
  • 21
  • 33
1

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.

Rizwan
  • 3,324
  • 3
  • 17
  • 38
1

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

Rakesha Shastri
  • 11,053
  • 3
  • 37
  • 50
  • This doesn't *work 100%*. try typing many letters. try typing `ff:ee:ed:da:abb` – ielyamani Sep 24 '18 at 13:39
  • There are a couple of other things (I'm not sure if the OP would need them), like : **1)** In your solution if you try to delete many letters from inside the string, the cursor keeps going to the end of the string. **2)** If you copy/paste a *space* is automatically inserted (should take care of that when `string.count > 1`). **3)** Check if the string contains only valid characters `let validChars = (0...9).map{String($0)} + ["a", "b", "c", "d", "e", "f"]` – ielyamani Sep 24 '18 at 14:13
  • By 100% i meant the logic for adding and removing the “:”. I should probably remove that. Got excited there :d I’ll add the information as a note and leave the core solution untouched so that it remains easy to understand. – Rakesha Shastri Sep 24 '18 at 16:08
  • your answer is the best here, I'm not sure why it's not the one most upvoted or accepted, it would help future questioners. – ielyamani Sep 24 '18 at 16:11
  • Note that this would allow the user to input invalid characters in the field. mac address string only have hexa characters "0"..."9" and "a"..."f". anything other than that shouldn't be allowed in your text field – Leo Dabus Sep 24 '18 at 18:10
  • @LeoDabus _"You should include other logic like character limit, character restrictions, copy-paste handling yourself. "_ – Rakesha Shastri Sep 24 '18 at 18:11
  • @LeoDabus nice sir, unfortunately i'm only this good atm. :) It's ok i'm learning from people like you. ^^ – Rakesha Shastri Sep 24 '18 at 18:13