Форматирование номера телефона на iOS

У меня есть текстовое поле, в которое пользователь вводит данные. Это поле для номера телефона. Если пользователь вводит 1234567890, я хочу, чтобы он отображался как (123)-(456)-7890 по мере ввода пользователем. Как это возможно?


person Moni Viki    schedule 19.05.2011    source источник


Ответы (21)


Это поможет вам

Формат (ххх) ххх-хххх

- (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;
}
person wan    schedule 19.05.2011
comment
Спасибо тебе большое. Он работал идеально, как я хотел. Это очень поможет новичкам вроде меня. - person Moni Viki; 19.05.2011
comment
Я использовал ваш код. но как я упомяну, какое это текстовое поле. У меня есть текстовое поле внутри пользовательской ячейки UITableviewcell. Пожалуйста, посмотрите на мою правку. - person Moni Viki; 19.05.2011
comment
Установите тег для текстового поля, в котором вы хотите отформатировать номер телефона, и игнорируйте другое текстовое поле на основе значений тега. - person wan; 19.05.2011
comment
не получится, если выделить и удалить кусок телефонного номера - person lolol; 19.10.2012
comment
Установите тег для текстового поля, в котором вы хотите отформатировать номер телефона, и игнорируйте другое текстовое поле на основе значений тега. Можете ли вы объяснить тег для меня? мой TextField называется phoneField. Спасибо - person Scubadivingfool; 09.05.2013
comment
Это может работать для быстрого и грязного решения, но ему не хватает поддержки, которую я хотел бы иметь. Он не работает для международных номеров, он не работает для номеров длиннее 10 цифр, он не форматирует числа при удалении или редактировании символов. - person Ethan Mick; 05.06.2013

Это казалось более ясным и гораздо лучше справляется с удалением любых нежелательных символов. Форматирует правильно для 1 (###) ###‑#### или (###) ###‑####

- (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;
}
person bryguy1300    schedule 28.01.2013
comment
Спасибо! Лучшее решение для связанных вопросов должно получить намного больше голосов. - person user1244109; 14.05.2013
comment
Спасибо. Я использовал модифицированную версию для формата xxx-xxx-xxxx. - person Dan; 09.09.2013
comment
Я бы предложил также добавить теги во все текстовые поля номера телефона и сделать это, чтобы избавиться от ведущих 1, если остальная часть номера будет удалена - (void) textFieldDidEndEditing: (UITextField *) textField { if (textField.tag == 99) { if([textField.text isEqualToString:@1 ]){ textField.text = nil; } } - person ColossalChris; 02.04.2014
comment
Или Исправьте проблему следующим образом: BOOL hasLeadingOne = length › 0 && [decimalString characterAtIndex:0] == '1'; if(textField.text.length == 2 && length) вернуть YES; if (length == 0 || (length › 10 && !hasLeadingOne) || (length › 11)) { textField.text = decimalString; вернуть НЕТ; } - person David; 22.10.2014
comment
Еще один используемый комментарий — если у вас мало текстовых полей — не забудьте проверить, какие из них вы проверяете с помощью textField.tag - person Nazir; 21.12.2015

Приведенный ниже код — это то, что я обычно использую. Формат другой, но вы получаете картину. Это будет обрабатывать ввод, такой как «123df#$@$gdfg45-+678dfg901», и вывод «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
person datinc    schedule 11.07.2013
comment
Было бы лучше вернуть PhoneNumberString по умолчанию, если длина меньше семи. - person NSNoob; 19.07.2016

Здесь мы написали собственный подкласс NSFormatter для телефонных номеров: https://github.com/edgecase/PhoneNumberFormatter.

Вы можете использовать его как любой другой подкласс NSFormatter.

person Michael Enriquez    schedule 28.02.2012
comment
Это общий формат??? и я просто добавляю файл .h/.m в свой проект, нужно что-то еще ?? - person Omarj; 25.03.2013

Большое спасибо за первый ответ, но я думаю, что этот метод -(int)getLength:(NSString*)mobileNumber бесполезен. Вы можете попробовать что-то вроде ниже:

- (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;
}
person Yangel    schedule 22.11.2012

Для тех из вас, кому требуется форматирование международного номера: https://code.google.com/p/libphonenumber/

Поставляется с реализациями C++, Java и JavaScript. Должно быть легко обернуть реализации C++ в файл .mm и написать вокруг него небольшую оболочку Objective-C.

person ekscrypto    schedule 10.02.2014
comment
Я попробовал это и заработал. К сожалению, размер библиотеки C++ составляет ~2 МБ, и для нее требуется около 40 МБ библиотек зависимостей. Самой большой зависимостью является библиотека International Components for Unicode, размер которой составляет около 35 МБ, поскольку он включает стандартную библиотеку данных размером около 16 МБ. Большая часть этого состоит из таблиц преобразования и информации о локали. Так что это решение не очень практично для приложения iOS. - person joshuakcockrell; 31.08.2018

Допустимый вариант: https://github.com/iziz/libPhoneNumber-iOS Все остальные ответы охватывает лишь небольшую часть возможностей и комбинаций, эта библиотека фактически анализирует и проверяет КАЖДЫЙ телефонный номер и идентифицирует:

  • Национальность
  • тип номера телефона
  • Национальный перевозчик
person Kappe    schedule 03.03.2015

Относится к номерам телефонов в США:

В дополнение к сообщению @wan я добавил условное выражение, если пользователь начинает с кода страны (1). Таким образом, он будет иметь следующий формат: 1 (XXX) XXX-XXXX вместо (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;        
}
person rizk.taker    schedule 08.04.2015

Возможно, вы могли бы использовать этот простой метод:

+ (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;
}

Предполагая, что вышеуказанный метод находится в классе Contact, просто используйте такой метод:

NSString* phoneNumber = @"085755023455";

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

В результате получится что-то вроде:

085-7550-2345-5
person yunhasnawa    schedule 19.10.2012

Вы можете использовать для этого библиотеку AKNumericFormatter. Он имеет средство форматирования и удобную категорию UITextField, он доступен в виде какаопода.

person Alexey Kozhevnikov    schedule 15.11.2013

Версия C# Xamarin.iOS наиболее исчерпывающего ответа о том, как форматировать телефон в iOS, приведена ниже.

    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;
    }
person Alex Sorokoletov    schedule 09.10.2014

Также для формата +x (xxx) xxx-xx-xx вы можете использовать что-то вроде этого простого решения:

+ (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;}      
person Aleksei Sakharov    schedule 20.01.2015

БЫСТРЫЙ

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
    }
person Dharmbir Singh    schedule 24.08.2015
comment
он отображает xxx-xx-xxxx и задается вопрос для (xxx)-(xxx)-xxxx - person mohsinj; 09.02.2017

Номер телефона в формате Swift

Улучшает ответ оппонента @datinc, ввод, такой как 1123df#$@$gdfg45-+678dfg901, будет выводиться как +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
}
person Intentss    schedule 06.06.2016

Это поможет вам

Формат (xxx) xxx-xxxx Для 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

    }
person pradip sutariya    schedule 04.04.2017

Таким образом, этот метод будет форматировать для (xxx) xxx - xxxx ....
это модификация текущего верхнего ответа и обрабатывает символы возврата.

- (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];
    }
}}

Надеюсь, поможет

person Bill    schedule 20.08.2013

REFormattedNumberField, вероятно, лучше всего. Просто укажите желаемый формат.

person ReDetection    schedule 26.09.2014

Вот простая категория, которая будет имитировать формат ввода

@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

пример использования

[@"87654321" formatDecimalsAs:@"1111 1111"] // returns @"8765 4321"
person Henrik Hartz    schedule 04.05.2016

  1. Удаляет все нецифровые символы
  2. Если осталось 7 цифр, 123-4567
  3. для 10 цифр, (123) 456-7890
  4. В противном случае, группы из трех человек. Чтобы настроить размер групп, измените значение, присвоенное параметру 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;
    }
    
person 56phil    schedule 15.12.2016
comment
Хороший пример кода! Не могли бы вы уточнить, что он делает? - person Mark van Straten; 16.12.2016

В 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):

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

Сначала добавьте UITextFieldDelegate в файл .h и делегируйте UITextField в файл nib.

Во-вторых, добавьте этот код в свой файл .m:

    - (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];
}
person Rudi    schedule 20.04.2017