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)
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)
这是我的看法.这与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)
此解决方案适用于没有国际拨号前缀(+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)
不幸的是,你必须自己做。联系人应用程序使用未记录的 API。由于某些原因,将输入格式化程序附加到文本字段在 iPhone 上不像在 Mac 上那样公开。请随时提交功能增强错误报告。
归档时间: |
|
查看次数: |
47163 次 |
最近记录: |