Пользовательский формат для преобразования NSNumber в NSString

В моем приложении есть UITextField, который получает номер.

Я хочу, чтобы это число было представлено в определенном формате, например: (62) 1234 1234

Проблема в том, что у меня уже есть контроль над методом -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string, но я не знаю, как мне сделать эту "маску"

В настоящее время я делаю так:

string = [textField.text stringByReplacingCharactersInRange:range withString:string];
string = [[string componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:string];
NSLog(@"%@", myNumber);

в конце этого кода у меня есть 2 вещи:

  1. string : строковое представление моего текста (например, 6212341234 как NSString )
  2. myNumber: номер для этой строки (например, 6212341234 как NSNumber)

как я могу создать эту строку: (62) 1234 1234 на основе myNumber или string?

ИЗМЕНИТЬ

Отвечая на вопрос Рдельмара:

В числе может быть 10 или 11 цифр, и я намерен разделить их следующим образом: (62) 1234 1234 или (62) 12345 1234


person Nicos Karalis    schedule 28.09.2012    source источник
comment
Всегда ли числа состоят из 10 цифр? И всегда ли вы хотите разделить его так, как показано выше?   -  person rdelmar    schedule 29.09.2012
comment
Это точно номер телефона? Похоже на то, из формата, которого вы пытаетесь достичь. Если это так, обработайте его как строку и используйте подстроки.   -  person Jere Käpyaho    schedule 29.09.2012
comment
это не номер телефона, теперь, когда я об этом думаю, его можно рассматривать как номер. но как мне это сделать?   -  person Nicos Karalis    schedule 29.09.2012
comment
Если бы это был номер телефона, вы могли бы рассуждать о нем с точки зрения кодов города, таких как (62) или (4), а затем группировать остальные в соответствии с соглашениями. Форматирование телефонных номеров различается для разных локалей с точки зрения группировки. Это также сильно отличается от обычной группировки чисел, т.е. не основано на количествах, таких как тысячи.   -  person Jere Käpyaho    schedule 29.09.2012
comment
хорошо... я понимаю вашу точку зрения. но я до сих пор не знаю, как реализовать это решение. Вы можете сформулировать ответ и опубликовать его как ответ?   -  person Nicos Karalis    schedule 29.09.2012
comment
Смотрите ответ @rdelmar ниже; использует подстроки, как я набросал.   -  person Jere Käpyaho    schedule 29.09.2012


Ответы (2)


Вы можете использовать NSRegularExpression...

- (NSString *) formattedString:(NSString *)inputString
{
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:([0-9]{2})([0-9]{5})([0-9]{4}))|(?:([0-9]{0,2}+)([0-9]{0,4}+)([0-9]{0,4}+))" options:0 error:&error];
    NSArray *components = [NSArray array];
    NSArray *matches = [regex matchesInString:inputString options:0 range:NSMakeRange(0, [inputString length])];
    NSTextCheckingResult *match = [matches objectAtIndex:0];
    for ( NSUInteger i = 1; i <= 3; ++i )
    {
        NSRange range = [match rangeAtIndex:i];
        if ( NSNotFound == range.location )
        {
            break;
        }
        components = [components arrayByAddingObject:[inputString substringWithRange:range]];
    }
    if ( 0 == [components count] )
    {
        for ( NSUInteger i = 4; i <= 6; ++i )
        {
            NSRange range = [match rangeAtIndex:i];
            components = [components arrayByAddingObject:[inputString substringWithRange:range]];
        }
    }
    return [NSString stringWithFormat:@"(%@) %@ %@",
            [components objectAtIndex:0],
            [components objectAtIndex:1],
            [components objectAtIndex:2]];
}


- (void) testFormatting
{
    NSLog(@"%@", [self formattedString:@"62123451234"]);
    NSLog(@"%@", [self formattedString:@"6212341234"]);
    NSLog(@"%@", [self formattedString:@"621234123"]);
    NSLog(@"%@", [self formattedString:@"62123412"]);
    NSLog(@"%@", [self formattedString:@"6212341"]);
    NSLog(@"%@", [self formattedString:@"621234"]);
    NSLog(@"%@", [self formattedString:@"62123"]);
    NSLog(@"%@", [self formattedString:@"6212"]);
    NSLog(@"%@", [self formattedString:@"621"]);
    NSLog(@"%@", [self formattedString:@"62"]);
    NSLog(@"%@", [self formattedString:@"6"]);
}

Результат вызова метода testFormatting:

(62) 12345 1234
(62) 1234 1234
(62) 1234 123
(62) 1234 12
(62) 1234 1
(62) 1234 
(62) 123 
(62) 12 
(62) 1 
(62)  
(6)  

Таким образом, вы можете передавать промежуточные строки форматировщику, и он будет пытаться делать правильные вещи.

person rsswtmr    schedule 29.09.2012

Вы можете сделать это примерно так (для 10-значных чисел):

-(NSString *)formatString:(NSString *) input {
    NSString *part1 = [NSString stringWithFormat:@"(%@)",[input substringToIndex:2]];
    NSString *part2 = [input substringWithRange:NSMakeRange(2, 4)];
    NSString *part3 = [input substringWithRange:NSMakeRange(6, 4)];
    NSString *formatted = [NSString stringWithFormat:@"%@ %@ %@",part1,part2,part3];
    return formatted;

}

Чтобы обрабатывать 10- или 11-значные числа, вам нужно будет добавить предложение if для проверки длины, а затем соответствующим образом изменить диапазоны частей 2 и 3.

После редактирования: Как насчет чего-то подобного. Я думаю, что это настолько хорошо, насколько это возможно. Он разобьет его на (xx) xxxx xxxx по мере ввода, а если вы наберете другую цифру, он разобьет его на (xx) xxxxx xxxx. Любой дальнейший ввод игнорируется.

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

    if (textField.text.length == 3)
        textField.text = [NSString stringWithFormat:@"%@) ",textField.text];

    if (textField.text.length == 9)
        textField.text = [NSString stringWithFormat:@"%@ ",textField.text];

    if (textField.text.length == 14) {
        NSString *part1 = [textField.text substringToIndex:9];
        part1 = [part1 stringByAppendingString:[textField.text substringWithRange:NSMakeRange(10, 1)]];
        NSString *part2 = [textField.text substringWithRange:NSMakeRange(11, 3)];
        textField.text = [NSString stringWithFormat:@"%@ %@",part1,part2];
    }

    if (textField.text.length > 14)
        return NO;

    return YES;
}
person rdelmar    schedule 28.09.2012
comment
в моем приложении форматирование строки выполняется в то же время, когда пользователь вводит новую цифру. из-за этого у меня нет полной строки с 10-11 цифрами. из-за этого substringWithRange: не работает - person Nicos Karalis; 29.09.2012
comment
Вы должны были упомянуть об этом в самом начале. Я не думаю, что есть какой-либо способ сделать это совершенно правильно, когда вы печатаете, потому что нет никакого способа узнать, собирается ли пользователь вводить 11-значное или 10-значное число. Таким образом, разрыв между двумя последними частями не может быть определен до тех пор, пока не будет введена последняя цифра. - person rdelmar; 29.09.2012