如何在 iOS 中为不同的区域代码实时格式化电话号码(使用 UITextfield 时)?

Posted

技术标签:

【中文标题】如何在 iOS 中为不同的区域代码实时格式化电话号码(使用 UITextfield 时)?【英文标题】:How to format phone number realtime (when using UITextfield) in iOS for different region codes? 【发布时间】:2015-02-04 06:49:51 【问题描述】:

我找到了“NBAsYouTypeFormatter”并参考了提供的演示。但是,我希望在用户在 UITextField 中输入电话号码时动态格式化电话号码。

请记住,就我而言,地区代码并不固定为一两个国家/地区,例如只有@“US”或只有其他。区域代码将由用户从下拉列表中选择,所选代码将由我通过以下行传递:

NBAsYouTypeFormatter *asYouTypeFormatter = [[NBAsYouTypeFormatter alloc] initWithRegionCode:@"US"];  // may be any other than 'US'
NSString *output = [asYouTypeFormatter inputString:@"9999988888"];

现在,当用户输入数字文本字段时,如何动态格式化数字文本字段?

【问题讨论】:

【参考方案1】:

我是这样实现的。我将从头开始解释。因此,新用户可以从头开始。

从here 下载 libPhoneNumber-iOS 库。在该链接页面的底部,您会找到需要添加到项目中的文件。

您的捆绑包应如下所示:

现在,请按照以下步骤实施。

(1) 在需要格式化文本字段的视图控制器中导入文件。

#import "NBPhoneMetaDataGenerator.h"
#import "NBPhoneNumberUtil.h"
#import "NBAsYouTypeFormatter.h"

并在头文件中创建 NBAsYouTypeFormatter 类型的实例:

NBAsYouTypeFormatter *asYouTypeFormatter;

(2) 在该视图控制器的 viewDidLoad 方法中,初始化之前获取的对象:

asYouTypeFormatter = [[NBAsYouTypeFormatter alloc] initWithRegionCode:@"IN"];

注意:@"IN" 代表印度。您可以将其设置为任何您想要的。请参阅将包含在 libPhoneNumber-ios 库中的 plist 文件以查看完整的区域代码列表。

(3) 在 UITextField 的委托方法中,动态管理你的 textfield 的文本。

#pragma mark
#pragma mark - Phone Number textfield formatting

# define LIMIT 18 // Or whatever you want

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

    // Just allow 18 digits
    if(!(([string length] + range.location) > LIMIT))
    
        // Something entered by user
        if(range.length == 0)
        
            [textNumber setText:[self.asYouTypeFormatter inputDigit:string]];
        

        // Backspace
        else if(range.length == 1)
        
            [textNumber setText:[self.asYouTypeFormatter removeLastDigit]];
        
    

    return NO;

希望对他人有所帮助!!!

【讨论】:

你能给我崩溃报告吗? 当我使用此代码时,第一次按下按钮所以效果很好,但第二次按下所以崩溃 + (NBPhoneMetaData *)getMetadataForRegion:(NSString *)regionCode [NBMetadataHelper initializeHelper]; if ([self hasValue:regionCode] == NO) return nil; 区域代码 = [区域代码大写字符串]; if ([cachedMetaDataKey isEqualToString:regionCode]) return cachedMetaData; if ([cachedMetaDataKey isEqualToString:regionCode]) 这里的这个函数得到床访问错误。 我已经通过添加一个屏幕截图来编辑我的答案,请参阅它。你的捆绑包应该是这样的。您是否添加了 CoreTelephony.framework 我不确定这个问题是否与您对该方法的实现直接相关,但如果光标位于文本字段的开头,它最终会将数字附加到末尾。 【参考方案2】:

在 UITextField 委托的方法中

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

    NSString *totalString = [NSString stringWithFormat:@"%@%@",textField.text,string];

    if (range.length == 1)
    
        // Delete button was hit.. so tell the method to delete the last char.
        NSError *error = nil;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error];
        totalString = [regex stringByReplacingMatchesInString:totalString options:0 range:NSMakeRange(0, [totalString length]) withTemplate:@""];
        totalString = [totalString substringToIndex:[totalString length] - 1];
    

    textField.text = [Utility formatPhoneNumber:totalString countryCode:@"theCountryCode"];

    return NO;

此函数将根据提供的国家/地区代码将您的字符串格式化为电话格式号码。

+ (NSString *)formatPhoneNumber:(NSString *)simpleNumber countryCode:(NSString *)countryCode

    if (simpleNumber.length == 0)
    
        return @"";
    

    NSInteger maxLen = 15;

    // use regex to remove non-digits(including spaces) so we are left with just the numbers
    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^[0-9+]]" 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 > maxLen)
    
        // remove last extra chars.
        simpleNumber = [simpleNumber substringToIndex:maxLen];
    

    NSString *firstChar = @"";
    BOOL countryCodeLen = countryCode.length;

    if (simpleNumber.length > 0)
    
        firstChar = [simpleNumber substringToIndex:1];
    

    if ([firstChar isEqualToString:@"+"])
    
        //+1 (234)
        if (simpleNumber.length < 5 + countryCodeLen)
        
            NSString *string = [NSString stringWithFormat:@"(\\d%d)(\\d+)",countryCodeLen];
            //            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d1)(\\d+)"
            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:string
                                                                   withString:@"$1 ($2)"
                                                                      options:NSRegularExpressionSearch
                                                                        range:NSMakeRange(0, [simpleNumber length])];
        
        //+1 (234) 567
        else if(simpleNumber.length < 8 + countryCodeLen)
        
            NSString *string = [NSString stringWithFormat:@"(\\d%d)(\\d3)(\\d+)",countryCodeLen];
            //            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d1)(\\d3)(\\d+)"
            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:string
                                                                   withString:@"$1 ($2) $3"
                                                                      options:NSRegularExpressionSearch
                                                                        range:NSMakeRange(0, [simpleNumber length])];
        
        //+1 (234) 567-
        else   // else do this one..
        
            NSString *string = [NSString stringWithFormat:@"(\\d%d)(\\d3)(\\d3)(\\d+)",countryCodeLen];
            //            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d1)(\\d3)(\\d3)(\\d+)"
            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:string
                                                                   withString:@"$1 ($2) $3-$4"
                                                                      options:NSRegularExpressionSearch
                                                                        range:NSMakeRange(0, [simpleNumber length])];
        
    
    else
    
        // 123 456 7890
        // format the number.. if it's less then 7 digits.. then use this regex.
        if (simpleNumber.length < 7)
        
            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d3)(\\d+)"
                                                                   withString:@"($1) $2"
                                                                      options:NSRegularExpressionSearch
                                                                        range:NSMakeRange(0, [simpleNumber length])];
        
        else   // else do this one..
        
            simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d3)(\\d3)(\\d+)"
                                                                   withString:@"($1) $2-$3"
                                                                      options:NSRegularExpressionSearch
                                                                        range:NSMakeRange(0, [simpleNumber length])];
        
    

    return simpleNumber;

希望有帮助

【讨论】:

感谢@Tai Le Anh。但是我将如何实时进行,即当用户在 UiTextField 中输入数字时。我在问题中提到的代码中已经发生了转换。 解决方案是实时的。对我来说效果很好。

以上是关于如何在 iOS 中为不同的区域代码实时格式化电话号码(使用 UITextfield 时)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 _layout.cshtml 中为不同区域动态渲染局部视图?

如何在 iOS7 SpriteKit 中为不同大小的图像设置动画?

如何通过Phonegap查找具有iOS格式的联系人电话号码?

iOS上国家代码的电话号码格式

如何在 iOS 中为不同的 IBAction 赋值?

如何使用 SQL 显示两个不同区域中时间戳之间的实时差异?