amin
amin

Reputation: 481

How to apply mobile number pattern on UITextField in Swift

I need to get user mobile phone number in Persian and English. And apply the phone number pattern to show. I found two solutions, each of them has a problem.

Number 1:

extension String{
    func applyPatternOnNumbers(pattern: String) -> String {
        let  replacmentCharacter: Character = "#"
        var pure = self.replacingOccurrences( of: "[^۰-۹0-9]", with: "", options: .regularExpression)
        for index in 0 ..< pattern.count {
            guard index < pure.count else { return pure }
            let stringIndex = String.Index.init(encodedOffset: index)
            let patternCharacter = pattern[stringIndex]
            guard patternCharacter != replacmentCharacter else { continue }
            pure.insert(patternCharacter, at: stringIndex)
        }
       return pure
    }
 }

use in editingChanged

class ViewController: UIViewController, UITextFieldDelegate {

    let textField = UITextField()
    override func viewDidLoad() {
        super.viewDidLoad()
        textField.frame = CGRect(x: 10, y: 50, width: 300, height: 50)
        textField.delegate = self
        textField.backgroundColor = UIColor.lightGray
        textField.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
        self.view.addSubview(textField)
    }

    @objc func editingChanged(){
        let pattern = "+# (###) ###-####"
        let mobile = textField.text
        textField.text = mobile!.applyPatternOnNumbers(pattern: pattern)
    }
}

When the number is typed in English for example +1800444777 the result is // +1 (800) 444-7777

But when the Persian numbers are typed for example +۱۸۰۰۴۴۴۷۷۷ the result is this // +۱ (۸۩ ´۷۷۷ 🤔

Number 2:

extension String{
      func applyPatternOnNumbers(pattern: String) -> String {
           let replacmentCharacter: Character = "#"
           let pureNumber = self.replacingOccurrences( of: "[^۰-۹0-9]", with: "", options: .regularExpression)
           var result = ""
           var pureNumberIndex = pureNumber.startIndex
           for patternCharacter in pattern {
               if patternCharacter == replacmentCharacter {
               guard pureNumberIndex < pureNumber.endIndex else { return result }
               result.append(pureNumber[pureNumberIndex])
               pureNumber.formIndex(after: &pureNumberIndex)
               } else {
                 result.append(patternCharacter)
               }
            }
        return result
     }
}

use this method is the same as the previous method This method works in both English and Persian

English "+1800444777" result is // +1 (800) 444-7777 Persian "+۱۸۰۰۴۴۴۷۷۷" result is // +۱ (۸۰۰) ۴۴۴-۷۷۷۷

But the problem is space & - , ( , ) , + chars can not to be removed on editing the textfield

Upvotes: 2

Views: 1190

Answers (1)

OOPer
OOPer

Reputation: 47886

Please replace the Number 2 extension to the following:

extension String{
    func applyPatternOnNumbers(pattern: String) -> String {
        let replacmentCharacter: Character = "#"
        let pureNumber = self.replacingOccurrences( of: "[^۰-۹0-9]", with: "", options: .regularExpression)
        var result = ""
        var pureNumberIndex = pureNumber.startIndex
        for patternCharacter in pattern {
            guard pureNumberIndex < pureNumber.endIndex else { return result }
            if patternCharacter == replacmentCharacter {
                result.append(pureNumber[pureNumberIndex])
                pureNumber.formIndex(after: &pureNumberIndex)
            } else {
                result.append(patternCharacter)
            }
        }
        return result
    }
}

This updated code checks if pureNumberIndex getting at the end or not, a little earlier that the former version.

With this change, the pattern needs to end with replacmentCharacter. I hope all the patterns you have listed up end with "#".

Upvotes: 3

Related Questions