【发布时间】:2014-04-01 07:25:22
【问题描述】:
在我的应用中,我将电话号码作为用户的输入。数字应为美国格式。我想像 (555)-888-888 那样动态地显示它。例如,当用户开始输入数字时,当他达到 4 位时,它会显示像这样的数字 (555)-4 等等。我尝试了 replaceString 方法,但我发现它不起作用。
【问题讨论】:
在我的应用中,我将电话号码作为用户的输入。数字应为美国格式。我想像 (555)-888-888 那样动态地显示它。例如,当用户开始输入数字时,当他达到 4 位时,它会显示像这样的数字 (555)-4 等等。我尝试了 replaceString 方法,但我发现它不起作用。
【问题讨论】:
查看 libPhoneNumber-iOS 库的 NBAsYouTypeFormatter 类。
您创建NSAsYouTypeFormatter 的新实例,并提供您的美国区域代码:
NBAsYouTypeFormatter *asYouTypeFormatter = [[NBAsYouTypeFormatter alloc] initWithRegionCode:REGION_CODE_STRING];
那么每次用户更改你拨打的电话号码时:
- (NSString*)inputDigit:(NSString*)nextChar;
或
- (NSString*)removeLastDigit;
这两种方法返回的NSString 是您的动态格式电话号码。
【讨论】:
NBAsYouTypeFormatter *asYouTypeFormatter = [[NBAsYouTypeFormatter alloc] initWithRegionCode:@"US"]; NSString *output = [asYouTypeFormatter inputString:@"9999988888"];
我将从头开始解释。因此,新用户可以从头开始。
从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)
{
[txtNumber setText:[asYouTypeFormatter inputDigit:string]];
}
// Backspace
else if(range.length == 1)
{
[txtNumber setText:[asYouTypeFormatter removeLastDigit]];
}
}
return NO;
}
希望对你有帮助!!!
【讨论】:
[asYouTypeFormatter inputDigit:yourString] :这是为您提供格式化字符串的关键方法
我找到了一个我想分享的解决方案,因为即使使用之前在这里介绍的解决方案,我也很难找到如何让它发挥作用。
我有一个 tableView,其单元格包含一个 textField。其中一个单元带有电话号码。在某些情况下,它可以已经填写,也可以不填写。
顺便说一句,这是在 Swift 中。
确保您的桥接头文件 nameOfYourProject-Bridging-Header 包含以下行:
#import "NBAsYouTypeFormatter.h"
为 NBAsYouTypeFormatter 声明一个属性:
private var phoneFormatter: NBAsYouTypeFormatter!
在 viewDidLoad 或属性的 didSet 中,用国家代码初始化 NBAsYouTypeFormatter:
// yourRegionCode is a 2-digit country code (ISO 3166)
phoneFormatter = NBAsYouTypeFormatter(regionCode: yourRegionCode)
将您的 viewController 声明为 TextFieldDelegate 并实现函数 shouldChangeCharactersInRange:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Phone number cell
if cellContainsPhoneNumber { // This is specific to your own tableView
// Formatting phone number as you type
let textWithoutSpaces = textField.text.stringByReplacingOccurrencesOfString(" ", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
phoneFormatter.inputString(textWithoutSpaces) // This is the initial value of the phoneFormatter each time the delegate method is called
let formattedNumber: String!
if string == "" {
formattedNumber = phoneFormatter.removeLastDigit()
} else {
formattedNumber = phoneFormatter.inputDigit(string)
}
// set the textField text with the new formattedNumber
textField.text = formattedNumber
return false
}
return true
}
这样,它的工作原理与 Apple 的联系人编辑机制完全相同。 如果这对您有帮助,请告诉我。
【讨论】:
这是一个更新后的 sn-p,通常适用于我(Swift 2.0):
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Allow up to 18 chars
if !(string.characters.count + range.location > 18) {
if range.length == 0 {
// original text didn't change
textField.text = phoneFormatter?.inputDigit(string)
} else if range.length == 1 {
// user pressed backspace
textField.text = phoneFormatter?.removeLastDigit()
} else if range.length == textField.text?.characters.count {
// text was cleared
phoneFormatter?.clear()
textField.text = ""
}
}
return false
}
主要的改变是它允许用户按下“清除”按钮或全选 -> 清除。
有一些边缘情况,例如用户编辑电话号码中的特定数字,这无法处理但可以轻松添加。
【讨论】:
你可以在输入https://github.com/luximetr/AnyFormatKit时使用这个库来格式化输入
例子
let textInputController = TextInputController()
let textInput = TextInputField() // or TextInputView or any TextInput
textInputController.textInput = textInput // setting textInput
let formatter = TextInputFormatter(textPattern: "### (###) ###-##-##", prefix: "+12")
textInputController.formatter = formatter // setting formatter
在这种情况下,TextInputController 将格式化您的 textField 或 textView 中的文本。
【讨论】:
这是一个使用 libPhoneNumber 的解决方案,它还可以处理数字中间的编辑、剪切和粘贴、选择和键入等非平凡的情况。它使光标保持稳定并且不会出现意外行为。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(range.location == textField.text.length && range.length == 0)
{
// Something added at end
textField.text = [numberFormatter inputDigit:string];
}
else if(range.location == textField.text.length-1 && range.length == 1)
{
// Backspace at end
textField.text = [numberFormatter removeLastDigit];
} else {
// Other modification in middle
NSString* input = textField.text;
// New cursor position after modification
NSUInteger cursorIdx = range.location + string.length;
// If backspacing to delete a format character - just reposition the cursor.
BOOL backspaceOnly = range.length == 1 && string.length == 0 && !isdigit([input characterAtIndex:range.location]);
if(!backspaceOnly) {
// make the modification, reformat the number
input = [input stringByReplacingCharactersInRange:range withString:string];
[numberFormatter clear];
BOOL rememberCursorPos = NO;
NSString* text;
// reinput the number to the formatter
// remembering the first digit position at or after the cursor
for (int i = 0; i < input.length; ++i)
{
if(i == cursorIdx) {
rememberCursorPos = YES;
}
char digit = [input characterAtIndex:i];
switch(digit) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if(!rememberCursorPos) {
text = [numberFormatter inputDigit:[NSString stringWithFormat:@"%c", digit]];
} else {
text = [numberFormatter inputDigitAndRememberPosition:[NSString stringWithFormat:@"%c", digit]];
rememberCursorPos = NO;
}
break;
}
}
// reformat the number
textField.text = text;
// get updated cursor position (formatter position starts at 1)
cursorIdx = numberFormatter.getRememberedPosition - 1;
}
// reposition the cursor
UITextPosition* position = [textField positionFromPosition:textField.beginningOfDocument offset:cursorIdx];
textField.selectedTextRange = [textField textRangeFromPosition:position toPosition:position];
}
return NO;
}
【讨论】: