UITextField for Phone Number
Asked Answered
S

25

51

I was wondering how I can format the textField that I'm using for a phone number (ie like the "Add New Contact" page on the iPhone. When I enter in a new mobile phone, ex. 1236890987 it formats it as (123) 689-0987.) I already have the keyboard set as the number pad.

Seaman answered 7/8, 2009 at 18:59 Comment(0)
P
70

Here is my solution.. works great! Formats the phone number in realtime. Note: This is for 10 digit phone numbers. And currently it auto formats it like (xxx) xxx-xxxx.. tweak to your hearts delight.

First in your shouldChangeCharactersInRange you want to gather the whole string for the phone text field and pass it to the validation/formatting function.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString* totalString = [NSString stringWithFormat:@"%@%@",textField.text,string];

// if it's the phone number textfield format it.
if(textField.tag==102 ) {
    if (range.length == 1) {
        // Delete button was hit.. so tell the method to delete the last char.
        textField.text = [self formatPhoneNumber:totalString deleteLastChar:YES];
    } else {
        textField.text = [self formatPhoneNumber:totalString deleteLastChar:NO ];
    }
    return false;
}

return YES; 
}

And here is where the phone number is formatted. The regex could probably be cleaned up a bit. But I have tested this code for a while and seems to pass all bells. Notice we also use this function to delete a number in the phone number. Works a little easier here because we already stripped out all the other non digits.

 -(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar {
if(simpleNumber.length==0) return @"";
// use regex to remove non-digits(including spaces) so we are left with just the numbers 
NSError *error = NULL;
 NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error];
 simpleNumber = [regex stringByReplacingMatchesInString:simpleNumber options:0 range:NSMakeRange(0, [simpleNumber length]) withTemplate:@""];

// check if the number is to long
if(simpleNumber.length>10) {
    // remove last extra chars.
    simpleNumber = [simpleNumber substringToIndex:10];
}

if(deleteLastChar) {
    // should we delete the last digit?
    simpleNumber = [simpleNumber substringToIndex:[simpleNumber length] - 1];
}

// 123 456 7890
// format the number.. if it's less then 7 digits.. then use this regex.
if(simpleNumber.length<7)
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d+)"
                                                           withString:@"($1) $2"
                                                              options:NSRegularExpressionSearch
                                                                range:NSMakeRange(0, [simpleNumber length])];

else   // else do this one..
    simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d{3})(\\d+)"
                                                           withString:@"($1) $2-$3"
                                                              options:NSRegularExpressionSearch
                                                                range:NSMakeRange(0, [simpleNumber length])];
return simpleNumber;
}
Provisory answered 5/11, 2012 at 7:16 Comment(10)
Worked well. Additionally, you can dismiss the keyboard after a full number is entered by adding the following to the formatPhoneNumber: method: if (simpleNumber.length == 10 && deleteLastChar == NO) { [textField resignFirstResponder]; } Boomer
How do you wire this to the actual text field?Goulash
Trying to add your method with the following code. Is this right? It's not working. case 3: { cell.textLabel.text = @"Phone" ; tf = phoneFieldTextField = [self makeTextField:self.phone placeholder:@"xxx-xxx-xxxx"]; phoneFieldTextField.keyboardType = UIKeyboardTypePhonePad; [self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES]; [cell addSubview:phoneFieldTextField]; break ; }Merchant
To wire it to your textfield in interface builder you need to make sure you have the delegate of the textfield set to file owner (most likely). Then add the 2 above methods to your .m file. Currently it's making sure it's a phone textfield by using the "textField.tag==102" statement. The tag for a textfield (or any other ui object) can be set in interface builder. So in this case I set the tag to 102 in interface builder.Provisory
BTW: Seems like I should be rewarded the answer? Yes Maybe?Provisory
@Provisory impossible - the account of the OP does not exist anymore, hence this answer will never be accepted. Ow btw, this is only good for North America as other countries use differing schemes.Klotz
@Klotz Yeah, North America only. Tweak to your hearts delight. Won't take much to make it work for other countries.Provisory
The idea looks nice, but it's too localized in my opinion. Only North America uses "(xxx) xxx-xxxx", and for everyone else abroad is really annoying! I suggest to look at code.google.com/p/libphonenumberWeigela
Great solution. very well use of regexRetaliation
You can get rid of the deleteLastChar stuff (which doesn't work for selecting and deleting or replacing) when you use this line instead of the original: NSString* totalString = [textField.text stringByReplacingCharactersInRange:range withString:string];Orling
R
37

Here's how you can do it in Swift 4:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    if (textField == phoneTextField) {
        let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)

        let decimalString = components.joined(separator: "") as NSString
        let length = decimalString.length
        let hasLeadingOne = length > 0 && decimalString.hasPrefix("1")

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

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

        if hasLeadingOne {
            formattedString.append("1 ")
            index += 1
        }
        if (length - index) > 3 {
            let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("(%@)", areaCode)
            index += 3
        }
        if length - index > 3 {
            let prefix = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("%@-", prefix)
            index += 3
        }

        let remainder = decimalString.substring(from: index)
        formattedString.append(remainder)
        textField.text = formattedString as String
        return false
    }
    else {
        return true
    }
}
Recitativo answered 28/10, 2014 at 3:6 Comment(5)
Thanks, vikzilla. It helped very much.Irrelevance
Might need to adjust: let decimalString = components.joinWithSeparator("") as NSStringGuru
Should be let hasLeadingOne = length > 0 && decimalString.characterAtIndex(0) == (49 as unichar) or even let hasLeadingOne = length > 0 && decimalString.hasPrefix("1")Ibadan
How Can I change it for this format "(+61) 428-74-5183" ?Spear
Dont forgot to add UITextFieldDelegate & in viewDidLoad textfield.delegate = self :)Alterable
P
13

Updated answer from Vikzilla for Swift 3:

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

    if textField == phoneTextField {

        let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        let components = (newString as NSString).components(separatedBy: NSCharacterSet.decimalDigits.inverted)

        let decimalString = components.joined(separator: "") as NSString
        let length = decimalString.length
        let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)

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

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

        if hasLeadingOne {
            formattedString.append("1 ")
            index += 1
        }
        if (length - index) > 3 {
            let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("(%@)", areaCode)
            index += 3
        }
        if length - index > 3 {
            let prefix = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("%@-", prefix)
            index += 3
        }

        let remainder = decimalString.substring(from: index)
        formattedString.append(remainder)
        textField.text = formattedString as String
        return false

    } else {
        return true
    }
}
Parrish answered 30/9, 2016 at 10:29 Comment(1)
How Can I change it for this format "(+61) 428-74-5183" ?Spear
B
10

I've been struggling with this for a couple of hours, here's what I have:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
     {
    NSUInteger currentLength = textField.text.length;
    NSCharacterSet *numbers = [NSCharacterSet decimalDigitCharacterSet];        

    if (range.length == 1) {
        return YES;
    }


    if ([numbers characterIsMember:[string characterAtIndex:0]]) {


        if ( currentLength == 3 ) 
        {

            if (range.length != 1) 
            {

                NSString *firstThreeDigits = [textField.text substringWithRange:NSMakeRange(0, 3)];

                NSString *updatedText;

                if ([string isEqualToString:@"-"]) 
                {
                    updatedText = [NSString stringWithFormat:@"%@",firstThreeDigits];
                }

                else 
                {
                    updatedText = [NSString stringWithFormat:@"%@-",firstThreeDigits];
                }

                [textField setText:updatedText];
            }           
        }

        else if ( currentLength > 3 && currentLength < 8 ) 
        {

            if ( range.length != 1 ) 
            {

                NSString *firstThree = [textField.text substringWithRange:NSMakeRange(0, 3)];
                NSString *dash = [textField.text substringWithRange:NSMakeRange(3, 1)];

                NSUInteger newLenght = range.location - 4;

                NSString *nextDigits = [textField.text substringWithRange:NSMakeRange(4, newLenght)];

                NSString *updatedText = [NSString stringWithFormat:@"%@%@%@",firstThree,dash,nextDigits];

                [textField setText:updatedText];

            }

        }

        else if ( currentLength == 8 ) 
        {

            if ( range.length != 1 ) 
            {
                NSString *areaCode = [textField.text substringWithRange:NSMakeRange(0, 3)];

                NSString *firstThree = [textField.text substringWithRange:NSMakeRange(4, 3)];

                NSString *nextDigit = [textField.text substringWithRange:NSMakeRange(7, 1)];

                [textField setText:[NSString stringWithFormat:@"(%@) %@-%@",areaCode,firstThree,nextDigit]];
            }

        }
    }

    else {
        return NO;
    }

    return YES;
}

I hope someone can contribute.

Bead answered 10/5, 2010 at 7:2 Comment(0)
K
10

Below function enforces (999)333-5555 format on the textField:

Swift 3:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if (textField == self.phone){
            let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
            let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)

            let decimalString = components.joined(separator: "") as NSString
            let length = decimalString.length
            let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)

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

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

            if hasLeadingOne {
                formattedString.append("1 ")
                index += 1
            }
            if (length - index) > 3 {
                let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
                formattedString.appendFormat("(%@)", areaCode)
                index += 3
            }
            if length - index > 3 {
                let prefix = decimalString.substring(with: NSMakeRange(index, 3))
                formattedString.appendFormat("%@-", prefix)
                index += 3
            }

            let remainder = decimalString.substring(from: index)
            formattedString.append(remainder)
            textField.text = formattedString as String
            return false
        } else {
            return true
        }
    }
Kaseykasha answered 18/7, 2017 at 14:6 Comment(0)
E
7

Here is my take of it. Which is close to what Apple does in the Phone and Contacts app (at least when your region is set to U.S., I am not sure if the behavior changes per region).

I was specifically interested in formatting up to 1 (123) 123-1234 and supporting longer numbers with no formatting. There is also a bug in just checking range.length == 1 (for delete/backspace) in the other solutions which prevents a user from selecting the entire string or part of it and pressing the delete/backspace key, this addresses that situation.

There are some strange behaviors that occur when you start selecting a range in the middle and edit, where the cursor always ends up at the end of the string due to setting the text fields value. I am not sure how to reposition the cursor in a UITextField, I presume Apple is actually using a UITextView in the Contacts and Phone apps as they maintain cursor position whilst doing this inline formatting, they seem to handle all the little nuances! I wish they'd just give us this out of the box.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSMutableString *newString = [NSMutableString stringWithString:textField.text];
    [newString replaceCharactersInRange:range withString:string];
    NSString *phoneNumberString = [self formattedPhoneNumber:newString];

    if (range.length >= 1) { // backspace/delete
        if (phoneNumberString.length > 1) {
            // the way we format the number it is possible that when the user presses backspace they are not deleting the last number
            // in the string, so we need to check if the last character is a number, if it isn't we need to delete everything after the
            // last number in the string
            unichar lastChar = [phoneNumberString characterAtIndex:phoneNumberString.length-1];
            NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890#*"];
            if (![numberCharacterSet characterIsMember:lastChar]) {
                NSRange numberRange = [phoneNumberString rangeOfCharacterFromSet:numberCharacterSet options:NSBackwardsSearch];
                phoneNumberString = [phoneNumberString substringToIndex:numberRange.location+1];
            }
        }
    }

    textField.text = phoneNumberString;

    return NO;
}

- (NSString *)formattedPhoneNumber:(NSString *)string {
    NSString *formattedPhoneNumber = @"";
    NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890#*+"];

    NSRange pauseRange = [string rangeOfString:@","];
    NSRange waitRange = [string rangeOfString:@";"];


    NSString *numberStringToFormat = nil;
    NSString *numberStringToAppend = @"";
    if (pauseRange.location != NSNotFound || waitRange.location != NSNotFound) {
        NSString *choppedString = [string substringToIndex:MIN(pauseRange.location, waitRange.location)];
        numberStringToFormat = [[choppedString componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedByString:@""];
        numberStringToAppend = [string substringFromIndex:MIN(pauseRange.location, waitRange.location)];
    } else {
        numberStringToFormat = [[string componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedByString:@""];
    }

    if ([numberStringToFormat hasPrefix:@"0"] || [numberStringToFormat hasPrefix:@"11"]) {
        // numbers starting with 0 and 11 should not be formatted
        formattedPhoneNumber = numberStringToFormat;

    } else if ([numberStringToFormat hasPrefix:@"1"]) {
        if (numberStringToFormat.length <= 1) {
            // 1
            formattedPhoneNumber = numberStringToFormat;
        } else if (numberStringToFormat.length <= 4) {
            // 1 (234)
            NSString *areaCode = [numberStringToFormat substringFromIndex:1];
            if (areaCode.length < 3) {
                formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@",
                                        [numberStringToFormat substringFromIndex:1]]; // 1 (XXX)
            } else {
                formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) ",
                                        [numberStringToFormat substringFromIndex:1]]; // 1 (XXX)
            }

        } else if (numberStringToFormat.length <= 7) {
            // 1 (234) 123
            formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) %@",
                                    [numberStringToFormat substringWithRange:NSMakeRange(1, 3)], //1 (XXX) 123
                                    [numberStringToFormat substringFromIndex:4]]; // 1 (234) XXX

        } else if (numberStringToFormat.length <= 11) {
            // 1 (123) 123-1234
            formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) %@-%@",
                                    [numberStringToFormat substringWithRange:NSMakeRange(1, 3)], //1 (XXX) 123
                                    [numberStringToFormat substringWithRange:NSMakeRange(4, 3)], //1 (234) XXX-1234
                                    [numberStringToFormat substringFromIndex:7]]; // 1 (234) 123-XXXX
        } else {
            // 1123456789012....
            formattedPhoneNumber = numberStringToFormat;
        }
    } else {
        if (numberStringToFormat.length <= 3) {
            // 123
            formattedPhoneNumber = numberStringToFormat;
        } else if (numberStringToFormat.length <= 7) {
            // 123-1234
            formattedPhoneNumber = [NSString stringWithFormat:@"%@-%@",
                                    [numberStringToFormat substringToIndex:3], // XXX-1234
                                    [numberStringToFormat substringFromIndex:3]]; // 123-XXXX
        } else if (numberStringToFormat.length <= 10) {
            // (123) 123-1234
            formattedPhoneNumber = [NSString stringWithFormat:@"(%@) %@-%@",
                                    [numberStringToFormat substringToIndex:3], // (XXX) 123-1234
                                    [numberStringToFormat substringWithRange:NSMakeRange(3, 3)], // (123) XXX-1234
                                    [numberStringToFormat substringFromIndex:6]]; // (123) 123-XXXX

        } else {
            // 123456789012....
            formattedPhoneNumber = numberStringToFormat;
        }
    }

    if (numberStringToAppend.length > 0) {
        formattedPhoneNumber = [NSString stringWithFormat:@"%@%@", formattedPhoneNumber, numberStringToAppend];
    }

    return formattedPhoneNumber;
}
Ex answered 6/1, 2014 at 21:32 Comment(0)
W
7

You can call this method whenever you need to update your textField:

extension String {
    func applyPatternOnNumbers(pattern: String, replacmentCharacter: 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 != replacmentCharacter else { continue }
            pureNumber.insert(patternCharacter, at: stringIndex)
        }
        return pureNumber
    }
}

Example:

 guard let text = textField.text else { return }
 textField.text = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#")
Wither answered 19/7, 2018 at 15:47 Comment(0)
M
6

This solution works great for North American numbers without the international dialing prefix (+1) and no extension. The number will be formatted as "(212) 555-1234". It will pre-type the ") " and the "-", but will also delete correctly.

Here is the -textField:shouldChangeCharactersInRange:replacementString that your text field delegate should implement:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField == self.myPhoneTextField) {
        NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
        BOOL deleting = [newText length] < [textField.text length];

        NSString *stripppedNumber = [newText stringByReplacingOccurrencesOfString:@"[^0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [newText length])];
        NSUInteger digits = [stripppedNumber length];

        if (digits > 10)
            stripppedNumber = [stripppedNumber substringToIndex:10];

        UITextRange *selectedRange = [textField selectedTextRange];
        NSInteger oldLength = [textField.text length];

        if (digits == 0)
            textField.text = @"";
        else if (digits < 3 || (digits == 3 && deleting))
            textField.text = [NSString stringWithFormat:@"(%@", stripppedNumber];
        else if (digits < 6 || (digits == 6 && deleting))
            textField.text = [NSString stringWithFormat:@"(%@) %@", [stripppedNumber substringToIndex:3], [stripppedNumber substringFromIndex:3]];
        else
            textField.text = [NSString stringWithFormat:@"(%@) %@-%@", [stripppedNumber substringToIndex:3], [stripppedNumber substringWithRange:NSMakeRange(3, 3)], [stripppedNumber substringFromIndex:6]];

        UITextPosition *newPosition = [textField positionFromPosition:selectedRange.start offset:[textField.text length] - oldLength];
        UITextRange *newRange = [textField textRangeFromPosition:newPosition toPosition:newPosition];
        [textField setSelectedTextRange:newRange];

        return NO;
    }

    return YES;
}
Midget answered 20/8, 2014 at 18:48 Comment(0)
D
4

Updated answer for Swift 2.0 from Vikzilla:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    sendButton.enabled = true
    let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
    let components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)

    let decimalString : String = components.joinWithSeparator("")
    let length = decimalString.characters.count
    let decimalStr = decimalString as NSString
    let hasLeadingOne = length > 0 && decimalStr.characterAtIndex(0) == (1 as unichar)

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

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

    if hasLeadingOne
    {
        formattedString.appendString("1 ")
        index += 1
    }
    if (length - index) > 3
    {
        let areaCode = decimalStr.substringWithRange(NSMakeRange(index, 3))
        formattedString.appendFormat("(%@)", areaCode)
        index += 3
    }
    if length - index > 3
    {
        let prefix = decimalStr.substringWithRange(NSMakeRange(index, 3))
        formattedString.appendFormat("%@-", prefix)
        index += 3
    }

    let remainder = decimalStr.substringFromIndex(index)
    formattedString.appendString(remainder)
    textField.text = formattedString as String
    return false
}

Worked excelente for me, hope it works for you too :)

Donothingism answered 6/10, 2015 at 19:14 Comment(1)
got an extraneous sendButtton reference in thereMesser
S
4

Swift 4 (and without NSString)

for format +X(XXX)XXX-XXXX or +X(XXX)XXX-XX-XX Updated and slightly

class ViewController: UIViewController, UITextFieldDelegate {

    var myPhoneNumber = String()

    @IBOutlet weak var phoneTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        phoneTextField.delegate = self
        phoneTextField.keyboardType = .phonePad
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
        if (textField == self.phoneTextField) && textField.text == ""{
            textField.text = "+7(" //your country code default
        }
    }

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

        if textField == phoneTextField {
            let res = phoneMask(phoneTextField: phoneTextField, textField: textField, range, string)
            myPhoneNumber = res.phoneNumber != "" ? "+\(res.phoneNumber)" : ""
            print("Phone - \(myPhoneNumber)  MaskPhone=\(res.maskPhoneNumber)")
            if (res.phoneNumber.count == 11) || (res.phoneNumber.count == 0) {
                //phone number entered or completely cleared
                print("EDIT END: Phone = \(myPhoneNumber)  MaskPhone = \(res.maskPhoneNumber)")
            }
            return res.result
        }
        return true
    }
}

extension UITextFieldDelegate {
    func phoneMask(phoneTextField: UITextField, textField: UITextField, _ range: NSRange, _ string: String) -> (result: Bool, phoneNumber: String, maskPhoneNumber: String) {
        let oldString = textField.text!
        let newString = oldString.replacingCharacters(in: Range(range, in: oldString)!, with: string)
        //in numString only Numeric characters
        let components = newString.components(separatedBy: CharacterSet.decimalDigits.inverted)
        let numString = components.joined(separator: "")

        let length = numString.count
        let maxCharInPhone = 11

        if newString.count < oldString.count { //backspace to work
            if newString.count <= 2 { //if now "+7(" and push backspace
                phoneTextField.text = ""
                return (false, "", "")
            } else {
                return (true, numString, newString) //will not in the process backspace
            }
        }

        if length > maxCharInPhone { // input is complete, do not add characters
            return (false, numString, newString)
        }
        var indexStart, indexEnd: String.Index
        var maskString = "", template = ""
        var endOffset = 0

        if newString == "+" { // allow add "+" if first Char
            maskString += "+"
        }
        //format +X(XXX)XXX-XXXX
        if length > 0 {
            maskString += "+"
            indexStart = numString.index(numString.startIndex, offsetBy: 0)
            indexEnd = numString.index(numString.startIndex, offsetBy: 1)
            maskString += String(numString[indexStart..<indexEnd]) + "("
        }
        if length > 1 {
            endOffset = 4
            template = ")"
            if length < 4 {
                endOffset = length
                template = ""
            }
            indexStart = numString.index(numString.startIndex, offsetBy: 1)
            indexEnd = numString.index(numString.startIndex, offsetBy: endOffset)
            maskString += String(numString[indexStart..<indexEnd]) + template
        }
        if length > 4 {
            endOffset = 7
            template = "-"
            if length < 7 {
                endOffset = length
                template = ""
            }
            indexStart = numString.index(numString.startIndex, offsetBy: 4)
            indexEnd = numString.index(numString.startIndex, offsetBy: endOffset)
            maskString += String(numString[indexStart..<indexEnd]) + template
        }
        var nIndex: Int; nIndex = 7
//            //format +X(XXX)XXX-XX-XX  -> if need uncoment
//            nIndex = 9
//
//            if length > 7 {
//                endOffset = 9
//                template = "-"
//                if length < 9 {
//                    endOffset = length
//                    template = ""
//                }
//                indexStart = numString.index(numString.startIndex, offsetBy: 7)
//                indexEnd = numString.index(numString.startIndex, offsetBy: endOffset)
//                maskString += String(numString[indexStart..<indexEnd]) + template
//            }
        if length > nIndex {
            indexStart = numString.index(numString.startIndex, offsetBy: nIndex)
            indexEnd = numString.index(numString.startIndex, offsetBy: length)
            maskString += String(numString[indexStart..<indexEnd])
        }
        phoneTextField.text = maskString
        if length == maxCharInPhone {
            //dimiss kayboard
            phoneTextField.endEditing(true)
            return (false, numString, newString)
        }
        return (false, numString, newString)
    }
}
Saval answered 28/2, 2018 at 2:13 Comment(0)
K
3

Here is my Swift 2 code from slightly localised from a UK perspective.

It will format:

+11234567890 as +1 (123) 456 7890

+33123456789 as +33 1 23 45 67 89

+441234123456 as +44 1234 123456 (this has been further localised as 01234 123456) because I don't need to see the country code for UK numbers.

Call as follows:

initInternationalPhoneFormats() //this just needs to be done once

var formattedNo = formatInternationalPhoneNo("+11234567890")

If you have any other country codes and formats or improvements to the code please let me know.

Enjoy.

import Cocoa

extension String
{
    //extension from https://mcmap.net/q/23461/-get-nth-character-of-a-string-in-swift

    subscript (i: Int) -> Character
    {
        return self[self.startIndex.advancedBy(i)]
    }

}

var phoneNoFormat = [String : String]()
var localCountryCode: String? = "+44"

func initInternationalPhoneFormats() 
{
    if phoneNoFormat.count == 0
    {
         phoneNoFormat["0"] = "+44 #### ######" //local no (UK)
         phoneNoFormat["02"] = "+44 ## #### #####" //local no (UK) London

         phoneNoFormat["+1"] = "+# (###) ###-####" //US and Canada

         phoneNoFormat["+234"] = "+## # ### ####" //Nigeria
         phoneNoFormat["+2348"] = "+## ### ### ####" //Nigeria Mobile

         phoneNoFormat["+31"] = "+## ### ## ## ##" //Netherlands
         phoneNoFormat["+316"] = "+## # ## ## ## ##" //Netherlands Mobile
         phoneNoFormat["+33"] = "+## # ## ## ## ##" //France
         phoneNoFormat["+39"] = "+## ## ########" //Italy
         phoneNoFormat["+392"] = "+## #### #####" //Italy
         phoneNoFormat["+393"] = "+## ### #######" //Italy

         phoneNoFormat["+44"] = "+## #### ######" //United Kingdom
         phoneNoFormat["+442"] = "+## ## #### #####" //United Kingdom London

         phoneNoFormat["+51"] = "+## # ### ####" //Peru
         phoneNoFormat["+519"] = "+## ### ### ###" //Peru Mobile
         phoneNoFormat["+54"] = "+## ### ### ####" //Argentina
         phoneNoFormat["+541"] = "+## ## #### ####" //Argentina
         phoneNoFormat["+549"] = "+## # ### ### ####" //Argentina
         phoneNoFormat["+55"] = "+## (##) ####-####" //Brazil
         phoneNoFormat["+551"] = "+## (##) ####-###" //Brazil Mobile?

         phoneNoFormat["+60"] = "+## # #### ####" //Malaysia
         phoneNoFormat["+6012"] = "+## ## ### ####" //Malaysia Mobile
         phoneNoFormat["+607"] = "+## # ### ####" //Malaysia?
         phoneNoFormat["+61"] = "+## # #### ####" //Australia
         phoneNoFormat["+614"] = "+## ### ### ###" //Australia Mobile
         phoneNoFormat["+62"] = "+## ## #######" //Indonesia
         phoneNoFormat["+628"] = "+## ### ######" //Indonesia Mobile
         phoneNoFormat["+65"] = "+## #### ####" //Singapore

         phoneNoFormat["+90"] = "+## (###) ### ## ##" //Turkey
     }
 }

 func getDiallingCode(phoneNo: String) -> String
 {
     var countryCode = phoneNo
     while countryCode.characters.count > 0 && phoneNoFormat[countryCode] == nil
     {
         countryCode = String(countryCode.characters.dropLast())
     }
     if countryCode == "0"
     {
         return localCountryCode!
     }
     return countryCode
 }


 func formatInternationalPhoneNo(fullPhoneNo: String, localisePhoneNo: Bool = true) -> String
 {
     if fullPhoneNo == ""
     {
         return ""
     }
     initInternationalPhoneFormats()

     let diallingCode = getDiallingCode(fullPhoneNo)

     let localPhoneNo = fullPhoneNo.stringByReplacingOccurrencesOfString(diallingCode, withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)

     var filteredPhoneNo = (localPhoneNo.characters.filter{["0","1","2","3","4","5","6","7","8","9"].contains($0)})
     if filteredPhoneNo[0] == "0"
     {
         filteredPhoneNo.removeFirst()
     }

     let phoneNo:String = diallingCode + String(filteredPhoneNo)

     if let format = phoneNoFormat[diallingCode]
     {
         let formatLength = format.characters.count
         var formattedPhoneNo = [Character]()
         var formatPos = 0
         for char in phoneNo.characters
         {
             while formatPos < formatLength && format[formatPos] != "#" && format[formatPos] != "+"
             {
                 formattedPhoneNo.append(format[formatPos])
                 formatPos++
             }

             if formatPos < formatLength
             {
                 formattedPhoneNo.append(char)
                 formatPos++
             }
             else
             {
                 break
             }
         }
         if localisePhoneNo,
             let localCode = localCountryCode
         {
             return String(formattedPhoneNo).stringByReplacingOccurrencesOfString(localCode + " ", withString: "0", options: NSStringCompareOptions.LiteralSearch, range: nil) //US users need to remove the extra 0
         }
         return String(formattedPhoneNo)
     }
     return String(filteredPhoneNo)
 }
Kingfisher answered 13/2, 2016 at 9:33 Comment(0)
H
3

You can add phone number like as 000-000-0000 (10- Digit). Please refer this code.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField==Phone_TXT)
    {
        if (range.location == 12)
        {
            return NO;
        }

        // Backspace
        if ([string length] == 0)
            return YES;

        if ((range.location == 3) || (range.location == 7))
        {

            NSString *str    = [NSString stringWithFormat:@"%@-",textField.text];
            textField.text   = str;
        }

        return YES;
    }
}
Holmes answered 18/2, 2016 at 6:5 Comment(0)
A
3

My solution for +X (XXX) XXX-XXXX format. (SWIFT)

func textFieldDidBeginEditing(textField: UITextField) {
    if (textField == self.mobileField) {
        textField.text = "+"
    }
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if (textField == self.mobileField) {
        let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)

        if (newString.characters.count < textField.text?.characters.count && newString.characters.count >= 1) {
            return true                                                         // return true for backspace to work
        } else if (newString.characters.count < 1) {
            return false;                        // deleting "+" makes no sence
        }
        if (newString.characters.count > 17 ) {
           return false;
        }

        let components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)

        let decimalString = components.joinWithSeparator("") as NSString
        let length = decimalString.length

        var index = 0
        let formattedString = NSMutableString()
        formattedString.appendString("+")

        if (length >= 1) {
            let countryCode = decimalString.substringWithRange(NSMakeRange(0, 1))
            formattedString.appendString(countryCode)
            index += 1
        }

        if (length > 1) {
            var rangeLength = 3
            if (length < 4) {
                rangeLength = length - 1
            }
            let operatorCode = decimalString.substringWithRange(NSMakeRange(1, rangeLength))
            formattedString.appendFormat(" (%@) ", operatorCode)
            index += operatorCode.characters.count
        }

        if (length > 4) {
            var rangeLength = 3
            if (length < 7) {
                rangeLength = length - 4
            }
            let prefix = decimalString.substringWithRange(NSMakeRange(4, rangeLength))
            formattedString.appendFormat("%@-", prefix)
            index += prefix.characters.count
        }

        if (index < length) {
            let remainder = decimalString.substringFromIndex(index)
            formattedString.appendString(remainder)
        }

        textField.text = formattedString as String

        if (newString.characters.count == 17) {
            textField.resignFirstResponder()
        }

        return false
    }

    return true
}
Astrology answered 11/4, 2016 at 16:49 Comment(0)
P
3

Swift 5+

Its an updated version of @Дарія Прокопович answer.

extension String {
  func applyPatternOnNumbers(pattern:String = "+# (###) ###-####", replacmentCharacter: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(encodedOffset: index)
            let patternCharacter = pattern[stringIndex]
            guard patternCharacter != replacmentCharacter else { continue }
            pureNumber.insert(patternCharacter, at: stringIndex)
        }
        return pureNumber
    }
}

Usage:

 @IBAction func phoneTextFieldValueChanged(_ sender: Any) {
      phoneTextField.text = phoneTextField.text!.applyPatternOnNumbers()
 }
Psych answered 12/4, 2020 at 12:19 Comment(0)
M
2

You can use this library https://github.com/luximetr/AnyFormatKit

Example

let textInputController = TextInputController()

let textInput = TextInputField() // or TextInputView or any TextInput
textInputController.textInput = textInput // setting textInput

let formatter = TextInputFormatter(textPattern: "### (###) ###-##-##", prefix: "+12")
textInputController.formatter = formatter // setting formatter

Just set your textField to this textInputController and it will format text with pattern, that you set.

Or

let phoneFormatter = TextFormatter(textPattern: "### (###) ###-##-##")
phoneFormatter.formattedText(from: "+123456789012") // +12 (345) 678-90-12

for format full string

Marmoset answered 21/11, 2017 at 8:53 Comment(0)
K
1

Unfortunately, you have to do it yourself. The contact app uses undocumented APIs. For some reason attaching input formatters to text fields is not exposed on the iPhone the way it is on the Mac. Feel free to file a feature enhancement bug report.

Krauss answered 7/8, 2009 at 22:12 Comment(0)
S
1

Hopefully, what i'm going to say, will be helpfull for new people programming on iOS, as I am. I did what zingle-dingle suggest (thanks a lot!). To help new ones the code plus what i'll list could help you. 1. you have to add the UITextFieldDelegate on the header file. 2. The UITextField should bind the delegate with the view, in my case the UIViewController, which is the header file. 3. the UITextField should be instatiated, it means, yourtextfile.delegate = self, on the ".m" file.

Supposed answered 12/3, 2013 at 7:57 Comment(0)
P
1

https://github.com/chebur/CHRTextFieldFormatter works for me like a charm.

Copy/paste from usage page:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.phoneNumberFormatter = [[CHRTextFieldFormatter alloc] initWithTextField:self.phoneNumberTextField mask:[CHRPhoneNumberMask new]];
    self.cardNumberFormatter = [[CHRTextFieldFormatter alloc] initWithTextField:self.cardNumberTextField mask:[CHRCardNumberMask new]];
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField == self.phoneNumberTextField) {
        return [self.phoneNumberFormatter textField:textField shouldChangeCharactersInRange:range replacementString:string];
    } else if (textField == self.cardNumberTextField) {
        return [self.cardNumberFormatter textField:textField shouldChangeCharactersInRange:range replacementString:string];
    } else {
        return YES;
    }
}

Also swift:

override func viewDidLoad() {
    super.viewDidLoad()
    self.phoneNumber.delegate = self
    self.phoneNumberFormatter = CHRTextFieldFormatter(textField: self.phoneNumber, mask:CHRPhoneNumberMask())
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if textField == self.phoneNumber {
        return self.phoneNumberFormatter.textField(textField, shouldChangeCharactersInRange: range, replacementString: string)
    }
    return true
}
Pomerania answered 25/2, 2016 at 16:25 Comment(0)
H
1

Here is my solution for 05xx xxx xxxx phone format. At the beginning I set

phoneTextField.delegate = self
phoneTextField.text = "05" // I don't let user to change it.

It also covers copy/paste cases for cursor position.

Maybe it helps someone for different formats.

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

    if range.location == 0 || range.location == 1 {
        return false
    }

    var phone = (textField.text! as NSString).replacingCharacters(in: range, with: string)

    if phone.length > 13 {
        return false
    }

    phone = phone.replacingOccurrences(of: " ", with: "")
    if phone.characters.count > 7 {
        phone.insert(" ", at: phone.index(phone.startIndex, offsetBy: 4))
        phone.insert(" ", at: phone.index(phone.startIndex, offsetBy: 8))
    } else if phone.characters.count > 4 {
        phone.insert(" ", at: phone.index(phone.startIndex, offsetBy: 4))
    }

    let text = textField.text
    let stringToStart = text?.substring(to: (text?.index((text?.startIndex)!, offsetBy: range.location))!)

    let stringToStartCount = ((stringToStart?.components(separatedBy: " ").count)! > 1) ? (stringToStart?.components(separatedBy: " ").count)!-1 : 0

    var cursorIndex = range.location + string.length - stringToStartCount

    if cursorIndex > 7 {
        cursorIndex += 2
    } else if cursorIndex > 4 {
        cursorIndex += 1
    }

    textField.text = phone
    textField.selectedTextRange = textField.textRange(from: textField.position(from: textField.beginningOfDocument, offset: cursorIndex)!, to: textField.position(from: textField.beginningOfDocument, offset: cursorIndex)!)

    return false
}
Hausfrau answered 16/1, 2017 at 9:7 Comment(0)
C
1

Updated answer from "iOS Unit" for Swift 3 with format +X(XXX)XXX-XXXX:

func textFieldDidBeginEditing(_ textField: UITextField) {
        if (textField == self.phoneTextField) {
            textField.text = "+"
        }
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if (textField == self.phoneTextField) {
            let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)

            if (newString.characters.count < (textField.text?.characters.count)! && newString.characters.count >= 1) {
                return true                                                         // return true for backspace to work
            } else if (newString.characters.count < 1) {
                return false;                        // deleting "+" makes no sence
            }
            if (newString.characters.count > 17 ) {
                return false;
            }

            let components = newString.components(separatedBy: CharacterSet.decimalDigits.inverted)
            let decimalString = components.joined(separator: "") as NSString
            let length = decimalString.length

            var index = 0
            let formattedString = NSMutableString()
            formattedString.append("+")

            if (length >= 1) {
                let countryCode = decimalString.substring(with: NSMakeRange(0, 1))
                formattedString.append(countryCode)
                index += 1
            }

            if (length > 1) {
                var rangeLength = 3
                if (length < 4) {
                    rangeLength = length - 1
                }
                let operatorCode = decimalString.substring(with: NSMakeRange(1, rangeLength))
                formattedString.appendFormat(" (%@) ", operatorCode)
                index += operatorCode.characters.count
            }

            if (length > 4) {
                var rangeLength = 3
                if (length < 7) {
                    rangeLength = length - 4
                }
                let prefix = decimalString.substring(with: NSMakeRange(4, rangeLength))
                formattedString.appendFormat("%@-", prefix)
                index += prefix.characters.count
            }

            if (index < length) {
                let remainder = decimalString.substring(from: index)
                formattedString.append(remainder)
            }

            textField.text = formattedString as String

            if (newString.characters.count == 17) {
                textField.resignFirstResponder()
            }

            return false
        }

        return true
    }
Cementation answered 4/4, 2017 at 13:51 Comment(0)
D
0

u have to do to this manually . take a notification of textField and check length of field text and format it according to country. if any problem let me know. I have done this

Dannie answered 8/8, 2009 at 12:40 Comment(1)
Hey goeff, it would be awesome if you could show me the code to do this because I just started coding in objective-c and it's very confusing to me. Thanks in advance!!Washbasin
J
0

I have a solution for this but it is having some drawback, see if you can modify and use it. By using this you can achieve both restrict phone number to 10 digit and format it as per US format.

#define MAX_LENGTH 10

Implement it in UITextField Delegate method

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

{

 NSInteger insertDelta = string.length - range.length;

if (PhoneNumber_txt.text.length + insertDelta > MAX_LENGTH)
{
    return NO; // the new string would be longer than MAX_LENGTH
}
else {

    range.length = 3;
    range.location = 3;

    PhoneNumber_txt.text = [NSString stringWithFormat:@"(%@)%@-%@", [PhoneNumber_txt.text substringToIndex:3], [PhoneNumber_txt.text substringWithRange:range], [PhoneNumber_txt.text substringFromIndex:6]];
    return YES;
}
 }
Jolie answered 30/8, 2012 at 7:36 Comment(0)
M
0
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

NSCharacterSet* validationSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
NSArray* components = [string componentsSeparatedByCharactersInSet:validationSet];

if ([components count] > 1) {
    return NO;
}

NSString* newString = [textField.text stringByReplacingCharactersInRange:range
                                                                 withString:string];

NSArray* validComponents = [newString componentsSeparatedByCharactersInSet:validationSet];

static const int localNumberMaxLength = 7;
static const int areaCodeMaxLength = 3;
static const int countryCodeMaxLength = 2;

newString = [validComponents componentsJoinedByString:@""];

if ([newString length] > localNumberMaxLength + areaCodeMaxLength + countryCodeMaxLength) {
    return NO;
}


NSLog(@"new string: %@", newString);

NSMutableString* resultString = [NSMutableString string];

NSInteger localNumberLength = MIN([newString length], localNumberMaxLength);

if (localNumberLength > 0) {
    NSString* number = [newString substringFromIndex:(int)[newString length] - localNumberLength];
    [resultString appendString:number];

    if ([resultString length] > 3) {
        [resultString insertString:@"-" atIndex:3];
    }
}

if ([newString length] > localNumberMaxLength) {
    NSInteger areaCodeLength = MIN((int)[newString length] - localNumberMaxLength, areaCodeMaxLength);
    NSRange areaRange = NSMakeRange((int)[newString length] - localNumberMaxLength - areaCodeLength, areaCodeLength);
    NSString* area = [newString substringWithRange:areaRange];

    area = [NSString stringWithFormat:@"(%@) ",area];

    [resultString insertString:area atIndex:0];
}

if ([newString length] > localNumberMaxLength + areaCodeMaxLength) {
    NSInteger countryCodeLength = MIN((int)[newString length] - localNumberMaxLength - areaCodeMaxLength, countryCodeMaxLength);
    NSRange countryCodeRange = NSMakeRange(0, countryCodeLength);
    NSString* countryCode = [newString substringWithRange:countryCodeRange];

    countryCode = [NSString stringWithFormat:@"+%@ ",countryCode];

    [resultString insertString:countryCode atIndex:0];
}

textField.text = resultString;
return NO;    

}

Marniemaro answered 31/7, 2015 at 11:53 Comment(1)
This question already has several answers, some of them with many upvotes. You should at least explain why you think your answer adds something that is new.Alternative
B
0

This is my solution using Swift 4 to format a number of type (123) 689-0987

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let currentText:String = textField.text else {return true}
    if string.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) != nil { return false }
    let newCount:Int = currentText.count + string.count - range.length
    let addingCharacter:Bool = range.length <= 0

    if(newCount == 1){
        textField.text = addingCharacter ? currentText + "(\(string)" : String(currentText.dropLast(2))
        return false
    }else if(newCount == 5){
        textField.text = addingCharacter ? currentText + ") \(string)" : String(currentText.dropLast(2))
        return false
    }else if(newCount == 10){
        textField.text = addingCharacter ? currentText + "-\(string)" : String(currentText.dropLast(2))
        return false
    }

    if(newCount > 14){
        return false
    }

    return true
}
Breakable answered 3/12, 2018 at 16:16 Comment(1)
FYI This breaks the use of auto suggestion. Great for just typing though.Deter
C
-1

I use this format X (XXX) XXX XX XX it is work in Turkey,

I use it with TableView with Swift 4

func formatToPhoneNumber(withPhoneTextField: UITextField, tableTextField: UITextField, range: NSRange, string: String) -> Bool {

    if (tableTextField == withPhoneTextField) {

        let newString = (tableTextField.text! as NSString).replacingCharacters(in: range, with: string)
        let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)

        let decimalString = components.joined(separator: "") as NSString
        let length = decimalString.length
        let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)

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

            return (newLength > 11) ? false : true
        }

        var index = 0 as Int
        let formattedString = NSMutableString()

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

        if (length - index) > 1{
            let zeroNumber = decimalString.substring(with: NSMakeRange(index, 1))
            formattedString.appendFormat("%@ ", zeroNumber)
            index += 1
        }

        if (length - index) > 3 {
            let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("(%@) ", areaCode)
            index += 3
        }

        if length - index > 3 {
            let prefix = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("%@ ", prefix)
            index += 3
        }

        if (length - index) > 3{
            let prefix = decimalString.substring(with: NSMakeRange(index, 2))
            formattedString.appendFormat("%@ ", prefix)
            index += 2
        }

        let remainder = decimalString.substring(from: index)
        formattedString.append(remainder)
        tableTextField.text = formattedString as String

        return false
    } else {
        return true
    }
}

and you can call this func in

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String, indexPath: IndexPath) -> Bool {

}

in any indexPath that your text field in it

for example my textfield in indexPath number 1 so the code will be

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String, indexPath: IndexPath) -> Bool {

    if indexPath.row == 1 {

        let phoneTextField = textField

        return formatToPhoneNumber(withPhoneTextField: phoneTextField, tableTextField: textField, range: range, string: string)

    }
}
Cyclist answered 11/6, 2018 at 14:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.