ios - 将 UILabel 内容格式化为美国电话号码格式

标签 ios objective-c nsstring

注意:当我发布这个问题时,我这里现在是晚上。如果我没有回复评论或答案,我会在早上回复。感谢您的理解:-)

这个想法是当用户触摸每个 UIButton 时将 UILabel 格式化为电话号码(美国格式)。

有一个键盘布局,当用户触摸每个数字键时,标签会显示它并动态格式化结果字符串。我写了一段我并不感到自豪的代码。我希望有人能帮助我以更好的方式或不同的方法来做到这一点。

screen

图像应该让您对它的外观有一个清晰的了解。现在,进入逻辑:

在下面的代码中,keyOne 是将数字附加到 UILabel 的 IBAction,keyBack 是删除它的 IBAction。

下面是输入电话号码的方式:

如果我输入1234567890:

after 1,2,3 the label is modified as 123- and gets assigned to string
Now string will be 123- and I continue touching 4567890

after 123-4567, when I touch 8, label is modified as (123)456-78 and gets assigned to string
Now string will be (123)456-7890

If I wish, I could continue entering more numbers. 
As per requirement, the number should lose its formatting. 
i.e. After (123)456-7890 if I press 1, it should become 12345678901

现在,诀窍是以完全相同的方式撤消这些步骤。这是泡菜。 如果我只输入 1234567890,_phoneNumber.text 将是 (123)456-7890,按 3 次后退键的结果应该是 123-4567。然后按回四次应该得到 123

但是,如果我输入 12345678901,_phoneNumber.text 将转到 (123)456-7890,然后丢失格式变为 12345678901,当我按回一次时,它应该变为 (123)456-7890 等等。

如果您创建一个单 View 应用程序类型的新项目并粘贴下面的内容(当然在创建按钮并使用 keyOne 连接 0-9 之后,使用 keyBack 返回)您会发现它工作正常。但是正如我上面提到的,我写了一段我不太自豪的代码。我觉得应该有一种更简单的方法来做到这一点。

ViewController.h

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *lengthParam;
@property (weak, nonatomic) IBOutlet UILabel *phoneNumber;
- (IBAction)keyOne:(id)sender;
- (IBAction)keyBack:(id)sender;
- (IBAction)clearAll:(id)sender;
@end

ViewController.m

#import "ViewController.h"

@interface ViewController () {
    BOOL isReformatted;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (IBAction)keyOne:(id)sender {
    UIButton *btn = (UIButton *)sender;
    NSString *str = [NSString stringWithString:self.phoneNumber.text];
    str = [str stringByAppendingString:btn.titleLabel.text];
    self.phoneNumber.text = str;
    if(str.length==4) self.phoneNumber.text = [self insertMinus:str]; //before the 4th number, insert '-' as a first step
    if(str.length==9) self.phoneNumber.text = [self insertParenthesis:str]; //remove - before the 4th number, encapsulate first 3 numbers inside () and add - at end of current number
    if(str.length>13) self.phoneNumber.text = [self plainFormat:str]; //if user enter more than 10 numbers, remove formatting
    self.lengthParam.text = [NSString stringWithFormat:@"%d",self.phoneNumber.text.length];
}

- (IBAction)keyBack:(id)sender {
    NSString *str = [NSString stringWithString:self.phoneNumber.text];
    NSString *newStr = nil;
    if(str.length>0) { //check for empty string
        if(str.length>11 && isReformatted==NO) newStr = [str substringToIndex:str.length-1]; //string.length > 10 which means plainFormat was called earlier and reFormat isn't called yet
        else if(str.length==11 && isReformatted == NO) { //string length is now 11
            if([str characterAtIndex:0]!='(') newStr = [self reFormat:str]; //if entered string is 12345678901, it is not reFormatted. remove last 1 and reFormat it as (123)456-7890
            else newStr = [self removeParenthesis:str]; //entered string itself is (123)456-78 so transform it as 123-4567
        } else { //we are dealing with a reformatted string of length 11 now.
            newStr = [str substringToIndex:str.length-1]; //String is (123)456-78, remove 8 and apply one of the below rules
            if(newStr.length==10) { //transform (123)456-7 as 123-4567
                newStr = [str substringToIndex:str.length-1];
                newStr = [self removeParenthesis:str];
            }
            if(newStr.length==4&&[newStr characterAtIndex:3]=='-') newStr = [self removeMinus:str]; //transform 123-4 to 123
        }
        self.phoneNumber.text = newStr;
        self.lengthParam.text = [NSString stringWithFormat:@"%d",self.phoneNumber.text.length];
    }
}

- (IBAction)clearAll:(id)sender {
    self.phoneNumber.text = @"";
    self.lengthParam.text = [NSString stringWithFormat:@"%d",self.phoneNumber.text.length];
}

- (NSString *)insertMinus:(NSString *)str {
    return [NSString stringWithFormat:@"%@-%@",[str substringToIndex:3],[str substringFromIndex:3]];
}

- (NSString *)insertParenthesis:(NSString *)str {
    NSString *c1 = [NSString stringWithFormat:@"(%@)",[str substringToIndex:3]];
    NSString *c2 = [NSString stringWithFormat:@"%@-%@",[str substringWithRange:NSMakeRange(4, 3)],[str substringFromIndex:7]];
    return [NSString stringWithFormat:@"%@%@",c1,c2];
}

- (NSString *)plainFormat:(NSString *)str {
    isReformatted = NO;
    str = [str stringByReplacingOccurrencesOfString:@"(" withString:@""];
    str = [str stringByReplacingOccurrencesOfString:@")" withString:@""];
    str = [str stringByReplacingOccurrencesOfString:@"-" withString:@""];
    str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
    return str;
}

- (NSString *)reFormat:(NSString *)str {
    isReformatted = YES;
    NSString *c1 = [NSString stringWithFormat:@"(%@)",[str substringToIndex:3]];
    NSString *c2 = [NSString stringWithFormat:@"%@-%@",[str substringWithRange:NSMakeRange(3, 3)],[str substringWithRange:NSMakeRange(6, 4)]];
    return [NSString stringWithFormat:@"%@%@",c1,c2];
}

- (NSString *)removeParenthesis:(NSString *)str {
    str = [self plainFormat:str];
    NSString *newStr = [NSString stringWithFormat:@"%@-%@",[str substringToIndex:3],[str substringWithRange:NSMakeRange(3, 4)]];
    return newStr;
}

- (NSString *)removeMinus:(NSString *)str {
    str = [self plainFormat:str];
    NSString *newStr = [NSString stringWithFormat:@"%@",[str substringToIndex:3]];
    return newStr;
}

@end

最佳答案

如果您渴望走上自己的电话号码格式化程序的道路,我会考虑执行以下操作:

  1. 存储用户输入而不格式化字符串。
  2. 每次按键后,重新格式化显示字符串。

类似于:

@property (nonatomic, copy) NSMutableString *backingString;
@property (weak, nonatomic) IBOutlet UILabel *phoneNumber;

- (void)viewWillAppear:(BOOL)animated
{
   [super viewWillAppear:animated];
   backingString = [NSMutableString string];
}

- (IBAction)keyOne:(id)sender
{
    UIButton *btn = (UIButton *)sender;
    [self.backingString appendString:btn.titleLabel.text];
    [self formatBackingString];
}


- (IBAction)keyBack:(id)sender
{
    [self.backingString deleteCharactersInRange:(NSRange){self.backingString.length - 1,1}];
    [self formatBackingString];
}

- (void)formatBackingString
{
    // Do your phone formatting here
    NSMutableString *formattedString = [NSMutableString string];
    NSInteger length = self.backingString.length;
    if (length < 3)
    {
       [formattedString appendString:self.backingString];
    }
    else if (length == 3)
    {
       [formattedString appendFormat:@"%@-", self.backingString];
    }
    else if (length < 8)
    {
        // etc...
    }
    self.phoneNumber.text = formattedString;
}

您还可以查看NSNumberFormatter .

关于ios - 将 UILabel 内容格式化为美国电话号码格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18597873/

相关文章:

ios - xcode 5.1 中的 Arm64 架构

ios - 为什么 "Use of undeclared type UITableView"发生在 Swift 中?

ios - 最佳实践 : Access properties

ios - 两个 TableViews 显示相同的数据?

objective-c - NSOperation 依赖和 completionBlock

ios - NSString 字符串与 CString :encoding: - not copying the Cstring?

ios - 从 Objective-C 中的字符串中删除短单词和字符

ios - NSDate 格式化

ios - 带有大字体和放大镜的 UITextView

ios - 当我返回 View Controller 时刷新 TableView 顶部的控件