UITextField电话号码

48 iphone cocoa-touch objective-c iphone-sdk-3.0

我想知道如何格式化我用于电话号码的textField(例如iPhone上的"添加新联系人"页面.当我输入新的手机时,例如1236890987,它将其格式化为(123 )689-0987.)我已经将键盘设置为数字键盘.

zin*_*gle 67

这是我的解决方案......效果很好!实时格式化电话号码.注意:这适用于10位数的电话号码.目前它自动格式化它像(xxx)xxx-xxxx ..调整到你心中的喜悦.

首先,您shouldChangeCharactersInRange要收集电话文本字段的整个字符串,并将其传递给验证/格式化功能.

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

// if it's the phone number textfield format it.
if(textField.tag==102 ) {
    if (range.length == 1) {
        // Delete button was hit.. so tell the method to delete the last char.
        textField.text = [self formatPhoneNumber:totalString deleteLastChar:YES];
    } else {
        textField.text = [self formatPhoneNumber:totalString deleteLastChar:NO ];
    }
    return false;
}

return YES; 
}
Run Code Online (Sandbox Code Playgroud)

这是电话号码格式化的地方.正则表达式可能会被清理一下.但我已经测试了这段代码一段时间,似乎已经通过了所有的钟声.请注意,我们还使用此功能删除电话号码中的号码.这里工作更容易,因为我们已经删除了所有其他非数字.

 -(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar {
if(simpleNumber.length==0) return @"";
// use regex to remove non-digits(including spaces) so we are left with just the numbers 
NSError *error = NULL;
 NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\\s-\\(\\)]" 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>10) {
    // remove last extra chars.
    simpleNumber = [simpleNumber substringToIndex:10];
}

if(deleteLastChar) {
    // should we delete the last digit?
    simpleNumber = [simpleNumber substringToIndex:[simpleNumber length] - 1];
}

// 123 456 7890
// format the number.. if it's less then 7 digits.. then use this regex.
if(simpleNumber.length<7)
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d+)"
                                                           withString:@"($1) $2"
                                                              options:NSRegularExpressionSearch
                                                                range:NSMakeRange(0, [simpleNumber length])];

else   // else do this one..
    simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d{3})(\\d+)"
                                                           withString:@"($1) $2-$3"
                                                              options:NSRegularExpressionSearch
                                                                range:NSMakeRange(0, [simpleNumber length])];
return simpleNumber;
}
Run Code Online (Sandbox Code Playgroud)


vik*_*lla 33

以下是在Swift 4中如何做到这一点:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
    if (textField == phoneTextField) {
        let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)

        let decimalString = components.joined(separator: "") as NSString
        let length = decimalString.length
        let hasLeadingOne = length > 0 && decimalString.hasPrefix("1")

        if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 {
            let newLength = (textField.text! as NSString).length + (string as NSString).length - range.length as Int

            return (newLength > 10) ? false : true
        }
        var index = 0 as Int
        let formattedString = NSMutableString()

        if hasLeadingOne {
            formattedString.append("1 ")
            index += 1
        }
        if (length - index) > 3 {
            let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("(%@)", areaCode)
            index += 3
        }
        if length - index > 3 {
            let prefix = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("%@-", prefix)
            index += 3
        }

        let remainder = decimalString.substring(from: index)
        formattedString.append(remainder)
        textField.text = formattedString as String
        return false
    }
    else {
        return true
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 应该让hasLeadingOne = length> 0 && decimalString.characterAtIndex(0)==(49 as unichar)或者甚至让hasLeadingOne = length> 0 && decimalString.hasPrefix("1") (3认同)

EPa*_*_Ed 12

更新了Vikzilla for Swift 3的答案:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if textField == phoneTextField {

        let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        let components = (newString as NSString).components(separatedBy: NSCharacterSet.decimalDigits.inverted)

        let decimalString = components.joined(separator: "") as NSString
        let length = decimalString.length
        let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)

        if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 {
            let newLength = (textField.text! as NSString).length + (string as NSString).length - range.length as Int

            return (newLength > 10) ? false : true
        }
        var index = 0 as Int
        let formattedString = NSMutableString()

        if hasLeadingOne {
            formattedString.append("1 ")
            index += 1
        }
        if (length - index) > 3 {
            let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("(%@)", areaCode)
            index += 3
        }
        if length - index > 3 {
            let prefix = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("%@-", prefix)
            index += 3
        }

        let remainder = decimalString.substring(from: index)
        formattedString.append(remainder)
        textField.text = formattedString as String
        return false

    } else {
        return true
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 10

我一直在努力解决这个问题几个小时,这就是我所拥有的:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
     {
    NSUInteger currentLength = textField.text.length;
    NSCharacterSet *numbers = [NSCharacterSet decimalDigitCharacterSet];        

    if (range.length == 1) {
        return YES;
    }


    if ([numbers characterIsMember:[string characterAtIndex:0]]) {


        if ( currentLength == 3 ) 
        {

            if (range.length != 1) 
            {

                NSString *firstThreeDigits = [textField.text substringWithRange:NSMakeRange(0, 3)];

                NSString *updatedText;

                if ([string isEqualToString:@"-"]) 
                {
                    updatedText = [NSString stringWithFormat:@"%@",firstThreeDigits];
                }

                else 
                {
                    updatedText = [NSString stringWithFormat:@"%@-",firstThreeDigits];
                }

                [textField setText:updatedText];
            }           
        }

        else if ( currentLength > 3 && currentLength < 8 ) 
        {

            if ( range.length != 1 ) 
            {

                NSString *firstThree = [textField.text substringWithRange:NSMakeRange(0, 3)];
                NSString *dash = [textField.text substringWithRange:NSMakeRange(3, 1)];

                NSUInteger newLenght = range.location - 4;

                NSString *nextDigits = [textField.text substringWithRange:NSMakeRange(4, newLenght)];

                NSString *updatedText = [NSString stringWithFormat:@"%@%@%@",firstThree,dash,nextDigits];

                [textField setText:updatedText];

            }

        }

        else if ( currentLength == 8 ) 
        {

            if ( range.length != 1 ) 
            {
                NSString *areaCode = [textField.text substringWithRange:NSMakeRange(0, 3)];

                NSString *firstThree = [textField.text substringWithRange:NSMakeRange(4, 3)];

                NSString *nextDigit = [textField.text substringWithRange:NSMakeRange(7, 1)];

                [textField setText:[NSString stringWithFormat:@"(%@) %@-%@",areaCode,firstThree,nextDigit]];
            }

        }
    }

    else {
        return NO;
    }

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

我希望有人能做出贡献.


Rao*_*Rao 10

下面的函数在textField上强制执行(999)333-5555格式:

斯威夫特3:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if (textField == self.phone){
            let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
            let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)

            let decimalString = components.joined(separator: "") as NSString
            let length = decimalString.length
            let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)

            if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 {
                let newLength = (textField.text! as NSString).length + (string as NSString).length - range.length as Int

                return (newLength > 10) ? false : true
            }
            var index = 0 as Int
            let formattedString = NSMutableString()

            if hasLeadingOne {
                formattedString.append("1 ")
                index += 1
            }
            if (length - index) > 3 {
                let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
                formattedString.appendFormat("(%@)", areaCode)
                index += 3
            }
            if length - index > 3 {
                let prefix = decimalString.substring(with: NSMakeRange(index, 3))
                formattedString.appendFormat("%@-", prefix)
                index += 3
            }

            let remainder = decimalString.substring(from: index)
            formattedString.append(remainder)
            textField.text = formattedString as String
            return false
        } else {
            return true
        }
    }
Run Code Online (Sandbox Code Playgroud)


Chr*_*ner 7

这是我的看法.这与Apple在电话和通讯录应用程序中所做的相近(至少当您的地区设置为美国时,我不确定每个地区的行为是否会发生变化).

我特别感兴趣的是格式化1 (123) 123-1234和支持更长的数字,没有格式化.range.length == 1在其他解决方案中仅检查(用于删除/退格)也存在一个错误,该错误阻止用户选择整个字符串或其中的一部分并按下删除/退格键,这解决了这种情况.

当您开始在中间选择一个范围并进行编辑时会发生一些奇怪的行为,由于设置了文本字段值,光标总是在字符串的末尾结束.我不确定如何重新定位光标UITextField,我认为Apple实际上UITextView在联系人和手机应用程序中使用a ,因为它们在执行此内联格式化时保持光标位置,它们似乎处理所有细微差别!我希望他们能够开箱即用.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSMutableString *newString = [NSMutableString stringWithString:textField.text];
    [newString replaceCharactersInRange:range withString:string];
    NSString *phoneNumberString = [self formattedPhoneNumber:newString];

    if (range.length >= 1) { // backspace/delete
        if (phoneNumberString.length > 1) {
            // the way we format the number it is possible that when the user presses backspace they are not deleting the last number
            // in the string, so we need to check if the last character is a number, if it isn't we need to delete everything after the
            // last number in the string
            unichar lastChar = [phoneNumberString characterAtIndex:phoneNumberString.length-1];
            NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890#*"];
            if (![numberCharacterSet characterIsMember:lastChar]) {
                NSRange numberRange = [phoneNumberString rangeOfCharacterFromSet:numberCharacterSet options:NSBackwardsSearch];
                phoneNumberString = [phoneNumberString substringToIndex:numberRange.location+1];
            }
        }
    }

    textField.text = phoneNumberString;

    return NO;
}

- (NSString *)formattedPhoneNumber:(NSString *)string {
    NSString *formattedPhoneNumber = @"";
    NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890#*+"];

    NSRange pauseRange = [string rangeOfString:@","];
    NSRange waitRange = [string rangeOfString:@";"];


    NSString *numberStringToFormat = nil;
    NSString *numberStringToAppend = @"";
    if (pauseRange.location != NSNotFound || waitRange.location != NSNotFound) {
        NSString *choppedString = [string substringToIndex:MIN(pauseRange.location, waitRange.location)];
        numberStringToFormat = [[choppedString componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedByString:@""];
        numberStringToAppend = [string substringFromIndex:MIN(pauseRange.location, waitRange.location)];
    } else {
        numberStringToFormat = [[string componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedByString:@""];
    }

    if ([numberStringToFormat hasPrefix:@"0"] || [numberStringToFormat hasPrefix:@"11"]) {
        // numbers starting with 0 and 11 should not be formatted
        formattedPhoneNumber = numberStringToFormat;

    } else if ([numberStringToFormat hasPrefix:@"1"]) {
        if (numberStringToFormat.length <= 1) {
            // 1
            formattedPhoneNumber = numberStringToFormat;
        } else if (numberStringToFormat.length <= 4) {
            // 1 (234)
            NSString *areaCode = [numberStringToFormat substringFromIndex:1];
            if (areaCode.length < 3) {
                formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@",
                                        [numberStringToFormat substringFromIndex:1]]; // 1 (XXX)
            } else {
                formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) ",
                                        [numberStringToFormat substringFromIndex:1]]; // 1 (XXX)
            }

        } else if (numberStringToFormat.length <= 7) {
            // 1 (234) 123
            formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) %@",
                                    [numberStringToFormat substringWithRange:NSMakeRange(1, 3)], //1 (XXX) 123
                                    [numberStringToFormat substringFromIndex:4]]; // 1 (234) XXX

        } else if (numberStringToFormat.length <= 11) {
            // 1 (123) 123-1234
            formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) %@-%@",
                                    [numberStringToFormat substringWithRange:NSMakeRange(1, 3)], //1 (XXX) 123
                                    [numberStringToFormat substringWithRange:NSMakeRange(4, 3)], //1 (234) XXX-1234
                                    [numberStringToFormat substringFromIndex:7]]; // 1 (234) 123-XXXX
        } else {
            // 1123456789012....
            formattedPhoneNumber = numberStringToFormat;
        }
    } else {
        if (numberStringToFormat.length <= 3) {
            // 123
            formattedPhoneNumber = numberStringToFormat;
        } else if (numberStringToFormat.length <= 7) {
            // 123-1234
            formattedPhoneNumber = [NSString stringWithFormat:@"%@-%@",
                                    [numberStringToFormat substringToIndex:3], // XXX-1234
                                    [numberStringToFormat substringFromIndex:3]]; // 123-XXXX
        } else if (numberStringToFormat.length <= 10) {
            // (123) 123-1234
            formattedPhoneNumber = [NSString stringWithFormat:@"(%@) %@-%@",
                                    [numberStringToFormat substringToIndex:3], // (XXX) 123-1234
                                    [numberStringToFormat substringWithRange:NSMakeRange(3, 3)], // (123) XXX-1234
                                    [numberStringToFormat substringFromIndex:6]]; // (123) 123-XXXX

        } else {
            // 123456789012....
            formattedPhoneNumber = numberStringToFormat;
        }
    }

    if (numberStringToAppend.length > 0) {
        formattedPhoneNumber = [NSString stringWithFormat:@"%@%@", formattedPhoneNumber, numberStringToAppend];
    }

    return formattedPhoneNumber;
}
Run Code Online (Sandbox Code Playgroud)


Fra*_*itt 5

此解决方案适用于没有国际拨号前缀(+1)且没有扩展名的北美号码.该号码将格式化为"(212)555-1234".它会预先键入")"和" - ",但也会正确删除.

这是-textField:shouldChangeCharactersInRange:replacementString您的文本字段委托应该实现的:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField == self.myPhoneTextField) {
        NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
        BOOL deleting = [newText length] < [textField.text length];

        NSString *stripppedNumber = [newText stringByReplacingOccurrencesOfString:@"[^0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [newText length])];
        NSUInteger digits = [stripppedNumber length];

        if (digits > 10)
            stripppedNumber = [stripppedNumber substringToIndex:10];

        UITextRange *selectedRange = [textField selectedTextRange];
        NSInteger oldLength = [textField.text length];

        if (digits == 0)
            textField.text = @"";
        else if (digits < 3 || (digits == 3 && deleting))
            textField.text = [NSString stringWithFormat:@"(%@", stripppedNumber];
        else if (digits < 6 || (digits == 6 && deleting))
            textField.text = [NSString stringWithFormat:@"(%@) %@", [stripppedNumber substringToIndex:3], [stripppedNumber substringFromIndex:3]];
        else
            textField.text = [NSString stringWithFormat:@"(%@) %@-%@", [stripppedNumber substringToIndex:3], [stripppedNumber substringWithRange:NSMakeRange(3, 3)], [stripppedNumber substringFromIndex:6]];

        UITextPosition *newPosition = [textField positionFromPosition:selectedRange.start offset:[textField.text length] - oldLength];
        UITextRange *newRange = [textField textRangeFromPosition:newPosition toPosition:newPosition];
        [textField setSelectedTextRange:newRange];

        return NO;
    }

    return YES;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以在需要更新textField时调用此方法:

extension String {
    func applyPatternOnNumbers(pattern: String, replacmentCharacter: Character) -> String {
        var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
        for index in 0 ..< pattern.count {
            guard index < pureNumber.count else { return pureNumber }
            let stringIndex = String.Index(encodedOffset: index)
            let patternCharacter = pattern[stringIndex]
            guard patternCharacter != replacmentCharacter else { continue }
            pureNumber.insert(patternCharacter, at: stringIndex)
        }
        return pureNumber
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

 guard let text = textField.text else { return }
 textField.text = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#")
Run Code Online (Sandbox Code Playgroud)


Ram*_*min 1

不幸的是,你必须自己做。联系人应用程序使用未记录的 API。由于某些原因,将输入格式化程序附加到文本字段在 iPhone 上不像在 Mac 上那样公开。请随时提交功能增强错误报告。