rmaddy / RMPhoneFormat

RMPhoneFormat provides a simple to use class for formatting phone numbers in iOS apps. The formatting should replicate what you would see in the Contacts app for the same phone number.
266 stars 61 forks source link

Formatting while editing phone number #16

Open k06a opened 10 years ago

k06a commented 10 years ago

I am trying to achieve UITextField with formatted phone number while user input progress. My algo:

1) Get only digits from phone field 2) Format digits as phone number 3) Set UITextFields text property new formatted phone number

All works fine, until user tries to edit phone number in the middle. I can not properly save and restore selectedRange because of formatting chars " -()"

Is there any solution for this problem?

k06a commented 10 years ago

Solved via saving number of digits to the right from cursor position:

func countDigitsRighterThatCursor(textField: UITextField) -> Int {
    let cursorPos = textField.selectedTextRange.start
    var digits = -1
    var index = 0
    for ch in textField.text.unicodeScalars {
        if digits == -1 && cursorPos == textField.positionFromPosition(textField.beginningOfDocument, offset: index) {
            digits = 0
        }
        if digits >= 0 && NSCharacterSet.decimalDigitCharacterSet().longCharacterIsMember(ch.value) {
            digits++
        }
        index++;
    }

    return digits
}

func setCursor(textField: UITextField, whereHaveDigitsFromRight digits: Int) {
    let length = countElements(textField.text)
    var index = 0
    var digitsSkipped = 0
    for ch in reverse(textField.text.unicodeScalars) {
        if digitsSkipped == digits {
            let pos = textField.positionFromPosition(textField.endOfDocument, inDirection: .Left, offset: index)
            textField.selectedTextRange = textField.textRangeFromPosition(pos, toPosition: pos)
            return
        }
        if NSCharacterSet.decimalDigitCharacterSet().longCharacterIsMember(ch.value) {
            digitsSkipped++
        }
        index++
    }
}

@IBAction func phoneChanged(textField: UITextField) {
    if countElements(textField.text) == 0 {
        return
    }

    let rightCountDigits = countDigitsRighterThatCursor(textField)
    textField.text = formattedPhoneNumber(textField.text)
    setCursor(textField, whereHaveDigitsFromRight: rightCountDigits)
}