Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting Phone number in Swift

I'm formatting my textfiled text once the user start typing the phone number into this format type 0 (555) 444 66 77 and it is working fine but once I get the number from the server I get it like this 05554446677 So please could you tell me how I can edit it in the same format once I get it fro the server?

My code once I start typing:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if textField == phoneNumberTextField{
        var newString = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
        var components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)

        var decimalString = "".join(components) as NSString
        var length = decimalString.length
        var hasLeadingOne = length > 0 && decimalString.characterAtIndex(0) == (1 as unichar)

        if length == 0 || (length > 11 && !hasLeadingOne) || length > 12{
            var newLength = (textField.text as NSString).length + (string as NSString).length - range.length as Int

            return (newLength > 11) ? false : true
        }
        var index = 0 as Int
        var formattedString = NSMutableString()

        if hasLeadingOne{
            formattedString.appendString("1 ")
            index += 1
        }

        if (length - index) > 1{
            var zeroNumber = decimalString.substringWithRange(NSMakeRange(index, 1))
            formattedString.appendFormat("%@ ", zeroNumber)
            index += 1
        }
        if (length - index) > 3{
            var areaCode = decimalString.substringWithRange(NSMakeRange(index, 3))
            formattedString.appendFormat("(%@) ", areaCode)
            index += 3
        }
        if (length - index) > 3{
            var prefix = decimalString.substringWithRange(NSMakeRange(index, 3))
            formattedString.appendFormat("%@ ", prefix)
            index += 3
        }
        if (length - index) > 3{
            var prefix = decimalString.substringWithRange(NSMakeRange(index, 2))
            formattedString.appendFormat("%@ ", prefix)
            index += 2
        }

        var remainder = decimalString.substringFromIndex(index)
        formattedString.appendString(remainder)
        textField.text = formattedString as String
        return false
    }else{
        return true
    }
}
like image 639
CAN Avatar asked Sep 02 '15 22:09

CAN


2 Answers

Masked number typing

/// mask example: `+X (XXX) XXX-XXXX`
func format(with mask: String, phone: String) -> String {
    let numbers = phone.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
    var result = ""
    var index = numbers.startIndex // numbers iterator

    // iterate over the mask characters until the iterator of numbers ends
    for ch in mask where index < numbers.endIndex {
        if ch == "X" {
            // mask requires a number in this place, so take the next one
            result.append(numbers[index])

            // move numbers iterator to the next index
            index = numbers.index(after: index)

        } else {
            result.append(ch) // just append a mask character
        }
    }
    return result
}

Call the above function from the UITextField delegate method:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return false }
    let newString = (text as NSString).replacingCharacters(in: range, with: string)
    textField.text = format(with: "+X (XXX) XXX-XXXX", phone: newString)
    return false
}

So, that works better.

"" => ""
"0" => "+0"
"412" => "+4 (12"
"12345678901" => "+1 (234) 567-8901"
"a1_b2-c3=d4 e5&f6|g7h8" => "+1 (234) 567-8"
like image 127
Roman Filippov Avatar answered Oct 25 '22 11:10

Roman Filippov


Really simple solution:

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

Usage:

guard let text = textField.text else { return }
textField.text = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#")
like image 71
Dariia Prokopovych Avatar answered Oct 25 '22 11:10

Dariia Prokopovych