在 UITextField 的开头添加一个常量国家代码
Adding a constant country code at beginning of UITextField
我有一个 UITextField,用户需要在其中输入一个 phone 数字。
这是现在的样子:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Auto-add hyphen before appending 4rd or 7th digit
//
//
if (range.length == 0 && (range.location == 3 || range.location == 7))
{
textField.text = [NSString stringWithFormat:@"%@-%@", textField.text, string];
return NO;
}
// Delete hyphen when deleting its trailing digit
//
//
if (range.length == 1 && (range.location == 4 || range.location == 8))
{
range.location--;
range.length = 2;
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:@""];
return NO;
}
// Prevent crashing undo bug – see note below.
//
//
if (range.length + range.location > textField.text.length)
{
return NO;
}
// Limit text field characters
//
//
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 12) ? NO : YES;
}
在第 3 位数字之后,我再次添加了一个连字符。我在这里想要实现的是在 UITextField
的开头添加一个国家代码作为常量,并且用户将无法删除它。假设美国国家/地区代码,那么 UITextField
文本将在 +1-
开头看起来像这样,然后在写完完整数字后它看起来像这样:+1-600-242-252
我该怎么做?
提前致谢!
为了在开始时保持一个常量,您基本上想要检查该常量是否仍然存在于建议的文本中。如果它不拒绝此类编辑。
您不应尝试在特定的编辑步骤中插入连字符。最好操纵整个字符串。
例如
- 测试字符串是否有效。即
starts with +1
- 删除您之前添加的所有连字符
- 重新插入所有连字符
在代码中,这看起来像这样:
- (void)viewDidLoad {
[super viewDidLoad];
self.textField.text = @"+1"; // start with a +1 in the textField otherwise we can't change the field at all
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (![proposedText hasPrefix:@"+1"]) {
// tried to remove the first +1
return NO;
}
NSString *formattedPhoneNumber = [proposedText substringFromIndex:2]; // without +1 prefix
NSString *unformattedPhoneNumber = [formattedPhoneNumber stringByReplacingOccurrencesOfString:@"-" withString:@""]; // without hypens
// start with the prefix
NSMutableString *newText = [NSMutableString stringWithString:@"+1"];
for (NSInteger i = 0; i < [unformattedPhoneNumber length]; i++) {
if (i % 3 == 0) {
// add a - every 3 characters. add one at the beginning as well
[newText appendString:@"-"];
}
// add each digit from the unformatted phonenumber
[newText appendString:[unformattedPhoneNumber substringWithRange:NSMakeRange(i, 1)]];
}
textField.text = newText;
return NO;
}
这仍然是一个非常幼稚的实现。它有几个问题,例如光标总是在末尾,因为我们手动设置了 textField 的 text
。所以用户不能轻易删除字符串中间的数字。当然有办法解决这个问题。 selectedTextRange
将是要使用的 属性。而且您不能真正将 phone 数字粘贴到字段中。当然,用户不能删除连字符。
在用户键入时进行格式化往往会很快变得复杂,因为有太多的边缘情况。但这应该让你开始。
此答案假设起始国家/地区代码字符串在末尾包含连字符,例如:self.countryCode = @"+1-";
。文本字段最初应包含“+1-”。
我的回答比您的初衷更全面,因为它处理了许多您忽略的用例,例如复制和粘贴多个字符的操作、不恰当的连字符删除、不恰当的连字符添加、中线插入等。虽然它仍然不完美,因为您的原始答案在某些方面不明确...例如,如果您指定用户只能输入数字,则代码可以更简洁。
下面的实现在整个注释中逐行描述。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Combine the new text with the old
NSMutableString *combinedText = [[textField.text stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:@"%@", string]] mutableCopy];
// If the user deletes part of the country code or tries
// to edit it in any way, don't allow it
if (combinedText.length < self.countryCode.length ||
![combinedText hasPrefix:self.countryCode]) {
return NO;
}
// Limit text field characters to 12
if (combinedText.length > self.countryCode.length + 12) {
return NO;
}
// If the user tries to add a hyphen where there's supposed
// to be a hyphen, allow them to do so.
if ([string isEqualToString:@"-"] &&
(range.location == self.countryCode.length + 3 ||
range.location == self.countryCode.length + 7)) {
return YES;
}
// Remove all the hyphens other than the one directly
// following the country code
[combinedText replaceOccurrencesOfString:@"-" withString:@"" options:0 range:NSMakeRange(self.countryCode.length, [combinedText length] - self.countryCode.length)];
// Auto-add the hyphens before the 4th and 7th digits
if (combinedText.length > self.countryCode.length + 3)
[combinedText insertString:@"-" atIndex:self.countryCode.length + 3];
if (combinedText.length > self.countryCode.length + 7)
[combinedText insertString:@"-" atIndex:self.countryCode.length + 7];
// Store the original cursor position
UITextPosition *pos = [textField selectedTextRange].start;
// Count up the original number of hyphens
NSUInteger originalNumberOfHyphens = [[textField.text componentsSeparatedByString:@"-"] count] - 1;
// Count up the new number of hyphens
NSUInteger newNumberOfHyphens = [[combinedText componentsSeparatedByString:@"-"] count] - 1;
// Create a cursor offset to reflect the difference
// in the number of hyphens
float offset = newNumberOfHyphens - originalNumberOfHyphens;
// Update the text field to contain the combined text
textField.text = combinedText;
// Update the cursor position appropriately
if (string.length > 0) {
UITextPosition* cursor = [textField positionFromPosition:[textField beginningOfDocument] offset:range.location + range.length + offset + string.length];
textField.selectedTextRange = [textField textRangeFromPosition:cursor toPosition:cursor];
} else {
UITextPosition* cursor = [textField positionFromPosition:pos inDirection:UITextLayoutDirectionLeft offset:1-offset];
textField.selectedTextRange = [textField textRangeFromPosition:cursor toPosition:cursor];
}
// No need to replace the string since it's already been done
return NO;
}
我有一个 UITextField,用户需要在其中输入一个 phone 数字。
这是现在的样子:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Auto-add hyphen before appending 4rd or 7th digit
//
//
if (range.length == 0 && (range.location == 3 || range.location == 7))
{
textField.text = [NSString stringWithFormat:@"%@-%@", textField.text, string];
return NO;
}
// Delete hyphen when deleting its trailing digit
//
//
if (range.length == 1 && (range.location == 4 || range.location == 8))
{
range.location--;
range.length = 2;
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:@""];
return NO;
}
// Prevent crashing undo bug – see note below.
//
//
if (range.length + range.location > textField.text.length)
{
return NO;
}
// Limit text field characters
//
//
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 12) ? NO : YES;
}
在第 3 位数字之后,我再次添加了一个连字符。我在这里想要实现的是在 UITextField
的开头添加一个国家代码作为常量,并且用户将无法删除它。假设美国国家/地区代码,那么 UITextField
文本将在 +1-
开头看起来像这样,然后在写完完整数字后它看起来像这样:+1-600-242-252
我该怎么做?
提前致谢!
为了在开始时保持一个常量,您基本上想要检查该常量是否仍然存在于建议的文本中。如果它不拒绝此类编辑。
您不应尝试在特定的编辑步骤中插入连字符。最好操纵整个字符串。
例如
- 测试字符串是否有效。即
starts with +1
- 删除您之前添加的所有连字符
- 重新插入所有连字符
在代码中,这看起来像这样:
- (void)viewDidLoad {
[super viewDidLoad];
self.textField.text = @"+1"; // start with a +1 in the textField otherwise we can't change the field at all
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (![proposedText hasPrefix:@"+1"]) {
// tried to remove the first +1
return NO;
}
NSString *formattedPhoneNumber = [proposedText substringFromIndex:2]; // without +1 prefix
NSString *unformattedPhoneNumber = [formattedPhoneNumber stringByReplacingOccurrencesOfString:@"-" withString:@""]; // without hypens
// start with the prefix
NSMutableString *newText = [NSMutableString stringWithString:@"+1"];
for (NSInteger i = 0; i < [unformattedPhoneNumber length]; i++) {
if (i % 3 == 0) {
// add a - every 3 characters. add one at the beginning as well
[newText appendString:@"-"];
}
// add each digit from the unformatted phonenumber
[newText appendString:[unformattedPhoneNumber substringWithRange:NSMakeRange(i, 1)]];
}
textField.text = newText;
return NO;
}
这仍然是一个非常幼稚的实现。它有几个问题,例如光标总是在末尾,因为我们手动设置了 textField 的 text
。所以用户不能轻易删除字符串中间的数字。当然有办法解决这个问题。 selectedTextRange
将是要使用的 属性。而且您不能真正将 phone 数字粘贴到字段中。当然,用户不能删除连字符。
在用户键入时进行格式化往往会很快变得复杂,因为有太多的边缘情况。但这应该让你开始。
此答案假设起始国家/地区代码字符串在末尾包含连字符,例如:self.countryCode = @"+1-";
。文本字段最初应包含“+1-”。
我的回答比您的初衷更全面,因为它处理了许多您忽略的用例,例如复制和粘贴多个字符的操作、不恰当的连字符删除、不恰当的连字符添加、中线插入等。虽然它仍然不完美,因为您的原始答案在某些方面不明确...例如,如果您指定用户只能输入数字,则代码可以更简洁。
下面的实现在整个注释中逐行描述。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Combine the new text with the old
NSMutableString *combinedText = [[textField.text stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:@"%@", string]] mutableCopy];
// If the user deletes part of the country code or tries
// to edit it in any way, don't allow it
if (combinedText.length < self.countryCode.length ||
![combinedText hasPrefix:self.countryCode]) {
return NO;
}
// Limit text field characters to 12
if (combinedText.length > self.countryCode.length + 12) {
return NO;
}
// If the user tries to add a hyphen where there's supposed
// to be a hyphen, allow them to do so.
if ([string isEqualToString:@"-"] &&
(range.location == self.countryCode.length + 3 ||
range.location == self.countryCode.length + 7)) {
return YES;
}
// Remove all the hyphens other than the one directly
// following the country code
[combinedText replaceOccurrencesOfString:@"-" withString:@"" options:0 range:NSMakeRange(self.countryCode.length, [combinedText length] - self.countryCode.length)];
// Auto-add the hyphens before the 4th and 7th digits
if (combinedText.length > self.countryCode.length + 3)
[combinedText insertString:@"-" atIndex:self.countryCode.length + 3];
if (combinedText.length > self.countryCode.length + 7)
[combinedText insertString:@"-" atIndex:self.countryCode.length + 7];
// Store the original cursor position
UITextPosition *pos = [textField selectedTextRange].start;
// Count up the original number of hyphens
NSUInteger originalNumberOfHyphens = [[textField.text componentsSeparatedByString:@"-"] count] - 1;
// Count up the new number of hyphens
NSUInteger newNumberOfHyphens = [[combinedText componentsSeparatedByString:@"-"] count] - 1;
// Create a cursor offset to reflect the difference
// in the number of hyphens
float offset = newNumberOfHyphens - originalNumberOfHyphens;
// Update the text field to contain the combined text
textField.text = combinedText;
// Update the cursor position appropriately
if (string.length > 0) {
UITextPosition* cursor = [textField positionFromPosition:[textField beginningOfDocument] offset:range.location + range.length + offset + string.length];
textField.selectedTextRange = [textField textRangeFromPosition:cursor toPosition:cursor];
} else {
UITextPosition* cursor = [textField positionFromPosition:pos inDirection:UITextLayoutDirectionLeft offset:1-offset];
textField.selectedTextRange = [textField textRangeFromPosition:cursor toPosition:cursor];
}
// No need to replace the string since it's already been done
return NO;
}