Phone number formatting on iOS

Objective CIosCocoa TouchPhone NumberNumber Formatting

Objective C Problem Overview


I have a text field where the user enters data. It's a phone number field. If the user enters 1234567890, I want it displayed as (123)-(456)-7890 as the user types. How is this possible?

Objective C Solutions


Solution 1 - Objective C

This will help you

Format (xxx) xxx-xxxx

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
	int length = (int)[self getLength:textField.text];
	//NSLog(@"Length  =  %d ",length);

	if(length == 10)
	{
		if(range.length == 0)
			return NO;
	}

	if(length == 3)
	{
		NSString *num = [self formatNumber:textField.text];
		textField.text = [NSString stringWithFormat:@"(%@) ",num];
	
		if(range.length > 0)
			textField.text = [NSString stringWithFormat:@"%@",[num substringToIndex:3]];
	}
	else if(length == 6)
	{
		NSString *num = [self formatNumber:textField.text];
		//NSLog(@"%@",[num  substringToIndex:3]);
		//NSLog(@"%@",[num substringFromIndex:3]);
		textField.text = [NSString stringWithFormat:@"(%@) %@-",[num  substringToIndex:3],[num substringFromIndex:3]];
	
		if(range.length > 0)
			textField.text = [NSString stringWithFormat:@"(%@) %@",[num substringToIndex:3],[num substringFromIndex:3]];
	}

	return YES;
}

- (NSString *)formatNumber:(NSString *)mobileNumber
{
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"+" withString:@""];

	NSLog(@"%@", mobileNumber);

	int length = (int)[mobileNumber length];
	if(length > 10)
	{
		mobileNumber = [mobileNumber substringFromIndex: length-10];
		NSLog(@"%@", mobileNumber);
	
	}

	return mobileNumber;
}

- (int)getLength:(NSString *)mobileNumber
{
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
	mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"+" withString:@""];

	int length = (int)[mobileNumber length];

	return length;
}

Solution 2 - Objective C

This felt more clear and handles removing any unwanted characters much more nicely. Formats correctly for 1 (###) ###‑#### or (###) ###‑####

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    NSArray *components = [newString componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
    NSString *decimalString = [components componentsJoinedByString:@""];
    
    NSUInteger length = decimalString.length;
    BOOL hasLeadingOne = length > 0 && [decimalString characterAtIndex:0] == '1';
    
    if (length == 0 || (length > 10 && !hasLeadingOne) || (length > 11)) {
        textField.text = decimalString;
        return NO;
    }
    
    NSUInteger index = 0;
    NSMutableString *formattedString = [NSMutableString string];
    
    if (hasLeadingOne) {
        [formattedString appendString:@"1 "];
        index += 1;
    }
    
    if (length - index > 3) {
        NSString *areaCode = [decimalString substringWithRange:NSMakeRange(index, 3)];
        [formattedString appendFormat:@"(%@) ",areaCode];
        index += 3;
    }
    
    if (length - index > 3) {
        NSString *prefix = [decimalString substringWithRange:NSMakeRange(index, 3)];
        [formattedString appendFormat:@"%@-",prefix];
        index += 3;
    }
    
    NSString *remainder = [decimalString substringFromIndex:index];
    [formattedString appendString:remainder];
    
    textField.text = formattedString;
    
    return NO;
}

Solution 3 - Objective C

The code bellow is what I typically use. The format is different but you get the picture. This will handle input such as '123df#$@$gdfg45-+678dfg901' and output '1 (234) 567-8901'

#import "NSString+phoneNumber.h"

@implementation NSString (phoneNumber)

-(NSString*) phoneNumber{
	static NSCharacterSet* set = nil;
	if (set == nil){
		set = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
	}
	NSString* phoneString = [[self componentsSeparatedByCharactersInSet:set] componentsJoinedByString:@""];
	switch (phoneString.length) {
		case 7: return [NSString stringWithFormat:@"%@-%@", [phoneString substringToIndex:3], [phoneString substringFromIndex:3]];
		case 10: return [NSString stringWithFormat:@"(%@) %@-%@", [phoneString substringToIndex:3], [phoneString substringWithRange:NSMakeRange(3, 3)],[phoneString substringFromIndex:6]];
		case 11: return [NSString stringWithFormat:@"%@ (%@) %@-%@", [phoneString substringToIndex:1], [phoneString substringWithRange:NSMakeRange(1, 3)], [phoneString substringWithRange:NSMakeRange(4, 3)], [phoneString substringFromIndex:7]];
		case 12: return [NSString stringWithFormat:@"+%@ (%@) %@-%@", [phoneString substringToIndex:2], [phoneString substringWithRange:NSMakeRange(2, 3)], [phoneString substringWithRange:NSMakeRange(5, 3)], [phoneString substringFromIndex:8]];
		default: return nil;
	}
}

@end

Solution 4 - Objective C

We wrote a custom NSFormatter subclass for phone numbers here: https://github.com/edgecase/PhoneNumberFormatter

You can use it like any other NSFormatter subclass.

Solution 5 - Objective C

Thanks so much for the first answer but, i think, that method -(int)getLength:(NSString*)mobileNumber is useless. You can try something like below:

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

int length = [[self formatNumber:[textField text]] length];

if (length == 10) {
    if(range.length == 0) {
        return NO;
    }
}

if (length == 3) {
    NSString *num = [self formatNumber:[textField text]];
    textField.text = [NSString stringWithFormat:@"(%@) ",num];
    if (range.length > 0) {
        [textField setText:[NSString stringWithFormat:@"%@",[num substringToIndex:3]]];
    }
}
else if (length == 6) {
    NSString *num = [self formatNumber:[textField text]];
    [textField setText:[NSString stringWithFormat:@"(%@) %@-",[num  substringToIndex:3],[num substringFromIndex:3]]];
    if (range.length > 0) {
        [textField setText:[NSString stringWithFormat:@"(%@) %@",[num substringToIndex:3],[num substringFromIndex:3]]];
    }
}

return YES;
}

- (NSString*)formatNumber:(NSString*)mobileNumber {
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"+" withString:@""];

int length = [mobileNumber length];

if (length > 10) {
    mobileNumber = [mobileNumber substringFromIndex: length-10];
}

return mobileNumber;
}

Solution 6 - Objective C

For those of you who require international number formatting: https://code.google.com/p/libphonenumber/

Comes with C++, Java and JavaScript implementations. Should be easy to wrap the C++ implementations in a .mm file and write a small Objective-C wrapper around it.

Solution 7 - Objective C

Maybe you could use this simple method:

+ (NSString*) formatPhoneNumber:(NSString *)phoneNumber codeLength:(int) code segmentLength:(int) segment
{
    NSString* result = @"";
    
    int length = [phoneNumber length];
    
    NSString* firstSegment = @"";
    NSString* restSegment = @"";
    
    for (int i=0; i<length; i++) {
        
        char c = [phoneNumber characterAtIndex:i];
        
        if(i < code)
            firstSegment = [firstSegment stringByAppendingFormat:@"%c", c];
        else
        {
            restSegment = [restSegment stringByAppendingFormat:@"%c", c];
            
            int threshold = (i - code) + 1;
            
            if((threshold % segment == 0) && (threshold > 0) && !(threshold > length))
                restSegment = [restSegment stringByAppendingFormat:@"%c", '-'];
        }
        
    }
    
    result = [result stringByAppendingFormat:@"%@-%@", firstSegment, restSegment];
    
    return result;
}

Assuming above method is in Contact class, just use the method like this:

NSString* phoneNumber = @"085755023455";

NSString* formattedNumber = [Contact formatPhoneNumber:phoneNumber codeLength:3 segmentLength:4];

That would be resulting something like:

085-7550-2345-5

Solution 8 - Objective C

A valid option is https://github.com/iziz/libPhoneNumber-iOS All the other answer cover only a small part of the possibilities and combinations, this library actually parse and validate EVERY phone number, and identify:

  • Nationality
  • phone number type
  • National carrier

Solution 9 - Objective C

Relevant for U.S. Phone Numbers:

Adding to @wan's post, I added a conditional statement if the user starts with the country code (1). That way, it will format to be: 1 (XXX) XXX-XXXX instead of (1XX) XXX-XXXX.

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    textField = self.phoneNumberTextField;
    
    NSInteger length = [self getLength:textField.text];
    //NSLog(@"Length  =  %d ",length);
    
    if ([textField.text hasPrefix:@"1"]) {
        if(length == 11)
        {
            if(range.length == 0)
                return NO;
        }
        if(length == 4)
        {
            NSString *num = [self formatNumber:textField.text];
            textField.text = [NSString stringWithFormat:@"%@ (%@) ",[num substringToIndex:1],[num substringFromIndex:1]];
            if(range.length > 0)
                textField.text = [NSString stringWithFormat:@"%@",[num substringToIndex:4]];
        }
        else if(length == 7)
        {
            NSString *num = [self formatNumber:textField.text];
            NSRange numRange = NSMakeRange(1, 3);
            textField.text = [NSString stringWithFormat:@"%@ (%@) %@-",[num substringToIndex:1] ,[num substringWithRange:numRange],[num substringFromIndex:4]];
            if(range.length > 0)
                textField.text = [NSString stringWithFormat:@"(%@) %@",[num substringToIndex:3],[num substringFromIndex:3]];
        }
        
    } else {
        if(length == 10)
        {
            if(range.length == 0)
                return NO;
        }

        if(length == 3)
        {
            NSString *num = [self formatNumber:textField.text];
            textField.text = [NSString stringWithFormat:@"(%@) ",num];
            if(range.length > 0)
                textField.text = [NSString stringWithFormat:@"%@",[num substringToIndex:3]];
        }
        else if(length == 6)
        {
            NSString *num = [self formatNumber:textField.text];

            textField.text = [NSString stringWithFormat:@"(%@) %@-",[num  substringToIndex:3],[num substringFromIndex:3]];
            if(range.length > 0)
                textField.text = [NSString stringWithFormat:@"(%@) %@",[num substringToIndex:3],[num substringFromIndex:3]];
        }
    }
    return YES;
}

-(NSString*)formatNumber:(NSString*)mobileNumber
{
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"+" withString:@""];
    
    NSLog(@"%@", mobileNumber);
    
    NSInteger length = [mobileNumber length];
    if(length > 10)
    {
        mobileNumber = [mobileNumber substringFromIndex: length-10];
        NSLog(@"%@", mobileNumber);
        
    }
    
    
    return mobileNumber;
}
-(NSInteger)getLength:(NSString*)mobileNumber
{
    
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
    mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"+" withString:@""];
    
    NSInteger length = [mobileNumber length];
    
    return length;        
}

Solution 10 - Objective C

You can use AKNumericFormatterlibrary for it. It has formatter and convenient UITextField category, it's available as a cocoapod.

Solution 11 - Objective C

C# Xamarin.iOS version of most comprehensive answer on how to do phone formatting in iOS is below

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        PhoneNumberTextField.ShouldChangeCharacters = ChangeCharacters;
    }

    private bool ChangeCharacters(UITextField textField, NSRange range, string replacementString)
    {
        var text = textField.Text;
        var newString = text.Substring(0, range.Location) + replacementString + text.Substring(range.Location + range.Length);
        var decimalString = Regex.Replace(newString, @"[^\d]", string.Empty);
        var length = decimalString.Length;
        var hasLeadingOne = length > 0 && decimalString[0] == '1';
        if ((length == 0) || (length > 10 && !hasLeadingOne) || (length > 11))
        {
            textField.Text = decimalString;
            return false;
        }
        var index = 0;
        var formattedString = "";
        if (hasLeadingOne)
        {
            formattedString += "1";
            index += 1;
        }
        if (length - index > 3)
        {
            var areaCode = decimalString.Substring(index, 3);
            formattedString += "(" + areaCode + ")";
            index += 3;
        }
        if (length - index > 3)
        {
            var prefix = decimalString.Substring(index, 3);
            formattedString += " " + prefix + "-";
            index += 3;
        }
        var remainder = decimalString.Substring(index);
        formattedString += remainder;
        textField.Text = formattedString;
        return false;
    }

Solution 12 - Objective C

Also for format +x (xxx) xxx-xx-xx you can use something like this simple solution:

+ (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *components = [newString componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
NSString *decimalString = [components componentsJoinedByString:@""];

if (decimalString.length > 11) {
    return NO;
}

NSMutableString *formattedString = [NSMutableString stringWithString:decimalString];

[formattedString insertString:@"+" atIndex:0];

if (formattedString.length > 2)
    [formattedString insertString:@" (" atIndex:2];

if (formattedString.length > 7)
    [formattedString insertString:@") " atIndex:7];

if (formattedString.length > 12)
    [formattedString insertString:@"-" atIndex:12];

if (formattedString.length > 15)
    [formattedString insertString:@"-" atIndex:15];


textField.text = formattedString;
return NO;}      

Solution 13 - Objective C

SWIFT

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {        
            let length = self.getTextLength(textField.text)
            
            
            
            if length == 10{
                if range.length == 0{
                    return false
                }
            }
            
            if length == 3{
                
                var num : String = self.formatNumber(textField.text)
                
                textField.text = num + "-"
                if(range.length > 0){
                    textField.text = (num as NSString).substringToIndex(3)
                }
            }
            else if length == 6{
                
                var num : String = self.formatNumber(textField.text)
                
                let prefix  = (num as NSString).substringToIndex(3)
                let postfix = (num as NSString).substringFromIndex(3)
                
                textField.text = prefix + "-" + postfix + "-"
                
                if range.length > 0{
                    textField.text = prefix + postfix
                }
            }
            
            return true
    }




func getTextLength(mobileNo: String) -> NSInteger{
        
        var str : NSString = mobileNo as NSString
        str = str.stringByReplacingOccurrencesOfString("(", withString: "")
        str = str.stringByReplacingOccurrencesOfString(")", withString: "")
        str = str.stringByReplacingOccurrencesOfString(" ", withString: "")
        str = str.stringByReplacingOccurrencesOfString("-", withString: "")
        str = str.stringByReplacingOccurrencesOfString("+", withString: "")
        
        return str.length
    }
    
    func formatNumber(mobileNo: String) -> String{
        var str : NSString = mobileNo as NSString
        str = str.stringByReplacingOccurrencesOfString("(", withString: "")
        str = str.stringByReplacingOccurrencesOfString(")", withString: "")
        str = str.stringByReplacingOccurrencesOfString(" ", withString: "")
        str = str.stringByReplacingOccurrencesOfString("-", withString: "")
        str = str.stringByReplacingOccurrencesOfString("+", withString: "")
        
        if str.length > 10{
            str = str.substringFromIndex(str.length - 10)
        }

        return str as String
    }

Solution 14 - Objective C

Swift Formatted Phone Number

Improves oppon @datinc's answer, input such as 1123df#$@$gdfg45-+678dfg901 will be output as +11(234)567-8901

func formattedPhone(phone: String) -> String?  {
    let notPhoneNumbers = NSCharacterSet.decimalDigitCharacterSet().invertedSet
    let str = phone.componentsSeparatedByCharactersInSet(notPhoneNumbers).joinWithSeparator("")

    let startIdx = str.startIndex
    let endIdx = str.endIndex

    let count = str.characters.count
    if count == 7 {
        return "\(str[startIdx..<startIdx.advancedBy(3)])-\(str[startIdx.advancedBy(3)..<endIdx])"
    }else if count == 10{
        return "(\(str[startIdx..<startIdx.advancedBy(3)]))\(str[startIdx.advancedBy(3)..<startIdx.advancedBy(6)])-\(str[startIdx.advancedBy(6)..<endIdx])"
    }
    else if count > 10{
        let extra = str.characters.count - 10
        return "+\(str[startIdx..<startIdx.advancedBy(extra)])(\(str[endIdx.advancedBy(-10)..<endIdx.advancedBy(-7)]))\(str[endIdx.advancedBy(-7)..<endIdx.advancedBy(-4)])-\(str[endIdx.advancedBy(-4)..<endIdx])"
    }
    return nil
}

Solution 15 - Objective C

This will help you

Format (xxx) xxx-xxxx For SWIFT 3.0

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let length = Int(getLength(mobileNumber: textField.text!))
        
        if length == 15 {
            if range.length == 0 {
                return false
            }
        }
        
        if length == 3 {
            
            let num = self.formatNumber(mobileNumber: textField.text!)
            
            textField.text = NSString(format:"(%@)",num) as String
            
            if range.length > 0{
                let index: String.Index = num.index(num.startIndex, offsetBy: 3)
                textField.text = NSString(format:"%@",num.substring(to: index)) as String
            }
            
        }else if length == 6 {
            let num = self.formatNumber(mobileNumber: textField.text!)
            let index: String.Index = num.index(num.startIndex, offsetBy: 3)
            
            textField.text = NSString(format:"(%@) %@-",num.substring(to: index), num.substring(from: index)) as String
            if range.length > 0{
                textField.text = NSString(format:"(%@) %@",num.substring(to: index), num.substring(from: index)) as String
            }
        }
        
        return true
    }
        
    func formatNumber(mobileNumber: String) -> String {
        var number = mobileNumber
        number = number.replacingOccurrences(of: "(", with: "")
        number = number.replacingOccurrences(of: ")", with: "")
        number = number.replacingOccurrences(of: " ", with: "")
        number = number.replacingOccurrences(of: "-", with: "")
        number = number.replacingOccurrences(of: "+", with: "")
        
        let length = Int(number.characters.count)
        
        if length > 15 {
            let index = number.index(number.startIndex, offsetBy: 15)

           number = number.substring(to: index)
        }
        
        return number
    }
    
    func getLength(mobileNumber: String) -> Int {
        
        var number = mobileNumber
        number = number.replacingOccurrences(of: "(", with: "")
        number = number.replacingOccurrences(of: ")", with: "")
        number = number.replacingOccurrences(of: " ", with: "")
        number = number.replacingOccurrences(of: "-", with: "")
        number = number.replacingOccurrences(of: "+", with: "")
        
        let length = Int(number.characters.count)
        return length
        
    }

Solution 16 - Objective C

NSString *str=@"[+]+91[0-9]{10}";
NSPredicate *no=[NSPredicate predicateWithFormat:@"SELF MATCHES %@",str];
if([no evaluateWithObject:txtMobileno.text]==NO
{ 
    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Warning" message:@"Please Enter correct contact no." delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];

    [alert show];
    [alert release];	
}

Solution 17 - Objective C

So this method will format for (xxx) xxx - xxxx ....
it is a modification of the current top answer and handles backspaces

- (IBAction)autoFormat:(UITextField *)sender {

NSString *mobileNumber = [NSString stringWithFormat:@"%@",sender.text];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"-" withString:@""];
mobileNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"+" withString:@""];

int length = [mobileNumber length];
if(length > 0 && [sender.text length] > self.oldLength){
    if(length >= 7 && length <= 10){
        sender.text = [NSString stringWithFormat:@"(%@) %@ - %@",[mobileNumber substringToIndex:3], [mobileNumber substringWithRange:NSMakeRange(3,3)],[mobileNumber substringWithRange:NSMakeRange(6,[mobileNumber length]-6)]];
    } else if(length >= 4 && length <= 6) {
        sender.text = [NSString stringWithFormat:@"(%@) %@",[mobileNumber substringToIndex:3], [mobileNumber substringWithRange:NSMakeRange(3,[mobileNumber length]-3)]];
    }
    if(length >= 11 && length % 4 == 3){
        NSString *lastChar = [sender.text substringFromIndex:[sender.text length] - 1];
        sender.text = [NSString stringWithFormat:@"%@ %@",[sender.text substringToIndex:[sender.text length] - 1],lastChar];
    }
    self.oldLength = [sender.text length];
} else if([sender.text length] < self.oldLength) {
    NSLog(@"deleted - ");
    self.oldLength = 0;

    sender.text = @"";
    for (int i = 0; i < [mobileNumber length]; i = i + 1) {
        sender.text = [NSString stringWithFormat:@"%@%@",sender.text,[mobileNumber substringWithRange:NSMakeRange(i, 1)]];
        [self autoFormat:sender];
    }
}}

hope it helps

Solution 18 - Objective C

REFormattedNumberField is probably the best. Just supply a format you wish.

Solution 19 - Objective C

+(NSString *) phoneNumberFormatterTextField:(NSString *)number forRange:(NSRange)range
{
    int length = (int)[[self getPhoneNumber:number] length];
    if(length == 3)
    {
        NSString *num = [MPosBaseScreenController getPhoneNumber:number];
        number = [num stringByReplacingOccurrencesOfString:@"(\\d{3})"
                                              withString:@"($1) "
                                                 options:NSRegularExpressionSearch
                                                   range:NSMakeRange(0, num.length)];
       
    }
    else if(length == 6 || length > 6 )
    {
        NSString *num = [MPosBaseScreenController getPhoneNumber:number];
        number = [num stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d{3})"
                                              withString:@"($1) $2 - "
                                                 options:NSRegularExpressionSearch
                                                   range:NSMakeRange(0, num.length)];
    }
       return number;
}

Solution 20 - Objective C

Here's a simple category which will mimic the format of the input

@interface NSString (formatDecimalsAs)
- (NSString *)formatDecimalsAs:(NSString *)formattedDecimals;
@end

@implementation NSString (formatDecimalsAs)
- (NSString *)formatDecimalsAs:(NSString *)formattedDecimals
{
    // insert non-digit characters from source string
    NSMutableString *formattedNumber = [self mutableCopy];
    for (int i = 0; i < formattedDecimals.length; i++)
    {
        if (i > formattedNumber.length)
        {
            break;
        }
        unichar character = [formattedDecimals characterAtIndex:i];
        if ([[NSCharacterSet decimalDigitCharacterSet].invertedSet characterIsMember:character])
        {
            [formattedNumber insertString:[NSString stringWithFormat:@"%c", character] atIndex:(NSUInteger) i];
        }
    }
    return formattedNumber;
}
@end

example use

[@"87654321" formatDecimalsAs:@"1111 1111"] // returns @"8765 4321"

Solution 21 - Objective C

  1. Removes all non-digit characters

  2. If 7 digits remain, 123-4567

  3. for 10 digits, (123) 456-7890

  4. Otherwise, groups of three. To adjust the size of the groups, change the value assigned to substrsize

    -(NSString*)formatPhone:(NSString*)phone {
    
         NSString *formattedNumber = [[phone componentsSeparatedByCharactersInSet:
                              [[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
                             componentsJoinedByString:@""];
    
    int substrSize = 3;
    NSMutableArray *t = [[NSMutableArray alloc] initWithCapacity:formattedNumber.length / substrSize + 1];
    switch (formattedNumber.length) {
        case 7:
            formattedNumber = [NSString stringWithFormat:@"%@-%@",
                           [formattedNumber substringToIndex:3],
                           [formattedNumber substringFromIndex:3]];
        break;
    
        case 10:
            formattedNumber = [NSString stringWithFormat:@"(%@) %@-%@",
                           [formattedNumber substringToIndex:3],
                           [formattedNumber substringWithRange:NSMakeRange(3, 3)],
                           [formattedNumber substringFromIndex:6]];
        break;
    
        default:
            for (int i = 0; i < formattedNumber.length / substrSize; i++) {
            [t addObject:[formattedNumber substringWithRange:NSMakeRange(i * substrSize, substrSize)]];
            }
            if (formattedNumber.length % substrSize) {
                [t addObject:[formattedNumber substringFromIndex:(substrSize * t.count)]];
        }
            formattedNumber = [t componentsJoinedByString:@" "];
        break;
     }
     return formattedNumber;
    }
    

Solution 22 - Objective C

In SWIFT 3

func formattedPhone(phone: String) -> String?  {
    let notPhoneNumbers = CharacterSet.decimalDigits.inverted
    let str = phone.components(separatedBy: notPhoneNumbers).joined(separator: "")
    
    let startIdx = str.startIndex
    let endIdx = str.endIndex
    
    let count = str.characters.count
    if count == 7 {
        return "\(str[startIdx..<startIdx.advance(3, for: str)])-\(str[startIdx.advance(3, for: str)..<endIdx])"
    }else if count == 10{
        return "+1 (\(str[startIdx..<startIdx.advance(3, for: str)])) \(str[startIdx.advance(3, for: str)..<startIdx.advance(6, for: str)])-\(str[startIdx.advance(6, for: str)..<endIdx])"
    }
    else if count > 10{
        let extra = str.characters.count - 10
        return "+\(str[startIdx..<startIdx.advance(extra, for: str)]) (\(str[endIdx.advance(-10, for: str)..<endIdx.advance(-7, for: str)])) \(str[endIdx.advance(-7, for: str)..<endIdx.advance(-4, for: str)])-\(str[endIdx.advance(-4, for: str)..<endIdx])"
    }
    return nil
}

Swift 3 string.index.advancedBy(3) alternate:

extension String.Index{
func advance(_ offset:Int, `for` string:String)->String.Index{
    return string.index(self, offsetBy: offset)
}
}

Solution 23 - Objective C

First, add UITextFieldDelegate to your .h file and Delegate your UITextField in the nib file.

Second, add this code to your .m file :

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
        {
            NSString *filter = @"(###)-(###)-####";
            
            if(!filter) return YES;
            
            NSString *changedString = [textField.text stringByReplacingCharactersInRange:range withString:string];
            
            if(range.length == 1 && 
               string.length < range.length &&
               [[textField.text substringWithRange:range] rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"0123456789"]].location == NSNotFound)
            {
                
                NSInteger location = changedString.length-1;
                if(location > 0)
                {
                    for(; location > 0; location--)
                    {
                        if(isdigit([changedString characterAtIndex:location]))
                        {
                            break;
                        }
                    }
                    changedString = [changedString substringToIndex:location];
                }
            }
            
            textField.text = [self filteredPhoneStringFromStringWithFilter:changedString :filter];
            
            return NO;
            
        }

    -(NSString*) filteredPhoneStringFromStringWithFilter:(NSString*)number : (NSString*)filter{
        NSUInteger onOriginal = 0, onFilter = 0, onOutput = 0;
        char outputString[([filter length])];
        BOOL done = NO;
    
    while(onFilter < [filter length] && !done)
    {
        char filterChar = [filter characterAtIndex:onFilter];
        char originalChar = onOriginal >= number.length ? '\0' : [number characterAtIndex:onOriginal];
        switch (filterChar) {
            case '#':
                if(originalChar=='\0')
                {
                    // We have no more input numbers for the filter.  We're done.
                    done = YES;
                    break;
                }
                if(isdigit(originalChar))
                {
                    outputString[onOutput] = originalChar;
                    onOriginal++;
                    onFilter++;
                    onOutput++;
                }
                else
                {
                    onOriginal++;
                }
                break;
            default:
                // Any other character will automatically be inserted for the user as they type (spaces, - etc..) or deleted as they delete if there are more numbers to come.
                outputString[onOutput] = filterChar;
                onOutput++;
                onFilter++;
                if(originalChar == filterChar)
                    onOriginal++;
                break;
        }
    }
    outputString[onOutput] = '\0'; // Cap the output string
    return [NSString stringWithUTF8String:outputString];
}
     

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMoni VikiView Question on Stackoverflow
Solution 1 - Objective CwanView Answer on Stackoverflow
Solution 2 - Objective Cbryguy1300View Answer on Stackoverflow
Solution 3 - Objective CdatincView Answer on Stackoverflow
Solution 4 - Objective CMichael EnriquezView Answer on Stackoverflow
Solution 5 - Objective CYangelView Answer on Stackoverflow
Solution 6 - Objective CekscryptoView Answer on Stackoverflow
Solution 7 - Objective CyunhasnawaView Answer on Stackoverflow
Solution 8 - Objective CKappeView Answer on Stackoverflow
Solution 9 - Objective Crizk.takerView Answer on Stackoverflow
Solution 10 - Objective CAlexey KozhevnikovView Answer on Stackoverflow
Solution 11 - Objective CAlex SorokoletovView Answer on Stackoverflow
Solution 12 - Objective CAleksei SakharovView Answer on Stackoverflow
Solution 13 - Objective CDharmbir SinghView Answer on Stackoverflow
Solution 14 - Objective Cuser160917View Answer on Stackoverflow
Solution 15 - Objective CPradip SutariyaView Answer on Stackoverflow
Solution 16 - Objective CupendraView Answer on Stackoverflow
Solution 17 - Objective CBillView Answer on Stackoverflow
Solution 18 - Objective CReDetectionView Answer on Stackoverflow
Solution 19 - Objective CAshim DahalView Answer on Stackoverflow
Solution 20 - Objective CHenrik HartzView Answer on Stackoverflow
Solution 21 - Objective C56philView Answer on Stackoverflow
Solution 22 - Objective CSaRaVaNaN DMView Answer on Stackoverflow
Solution 23 - Objective CRudiView Answer on Stackoverflow