- (void)textFieldDidChange:(UITextField *)textField {
NSInteger textLength = textField.text.length;
NSString *text = [textField text];
text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
//身份证18位限制
if (text.length >= 18) {
text = [text substringToIndex:18];
}
//添加空格分割
NSString *newString = @"";
while (text.length > 0) {
NSInteger subStringLength = newString.length == 0 ? 6 : 4;
NSString *subString = [text substringToIndex:MIN(text.length, subStringLength)];
newString = [newString stringByAppendingString:subString];
if (subString.length == subStringLength && [text length] > subStringLength) {
newString = [newString stringByAppendingString:@" "];
}
text = [text substringFromIndex:MIN(text.length, subStringLength)];
}
//中间插入的情况,textField赋值后默认光标到字符串末尾,所以这里重新设置光标位置
//在赋值之前,获取光标位置
NSRange selectRange = textField.selectedRange;
textField.text = newString.mutableCopy;
//光标位置不在末尾时 去重设光标位置,避免无效操作
if (selectRange.location != textLength) {
//为分割空格时 光标上前一步
NSString *sChar = [textField.text substringWithRange:NSMakeRange(selectRange.location - 1, 1)];
sChar = [sChar stringByReplacingOccurrencesOfString:@" " withString:@""];
if ([sChar length] == 0) {
selectRange.location = selectRange.location + 1;
}
//重新设置光标位置
[textField setSelectedRange:selectRange];
}
}
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UITextField (ExtentRange)
- (NSRange)selectedRange;
- (void)setSelectedRange:(NSRange)range;
@end
NS_ASSUME_NONNULL_END
#import "UITextField+ExtentRange.h"
@implementation UITextField (ExtentRange)
- (NSRange) selectedRange
{
UITextPosition* beginning = self.beginningOfDocument;
UITextRange* selectedRange = self.selectedTextRange;
UITextPosition* selectionStart = selectedRange.start;
UITextPosition* selectionEnd = selectedRange.end;
const NSInteger location = [self offsetFromPosition:beginning toPosition:selectionStart];
const NSInteger length = [self offsetFromPosition:selectionStart toPosition:selectionEnd];
return NSMakeRange(location, length);
}
- (void) setSelectedRange:(NSRange) range
{
UITextPosition* beginning = self.beginningOfDocument;
UITextPosition* startPosition = [self positionFromPosition:beginning offset:range.location];
UITextPosition* endPosition = [self positionFromPosition:beginning offset:range.location + range.length];
UITextRange* selectionRange = [self textRangeFromPosition:startPosition toPosition:endPosition];
[self setSelectedTextRange:selectionRange];
}
@end
身份证、银行卡、手机号等添加字符分割、位数限制的情况,大部分的iOS开发都会这么做过这样的需求。
我一直都觉得这是一个非常简单的需求,也一直不以为意。
今天跟同事聊这个问题的时候才发现我以前写这类功能的代码一直忽视了一些问题。
1、在中间插入或删除字符的时候,光标自动移动到字符串末尾
2、直接不给删除
等等各种不奇葩的问题。
并且参考过各类文章,大多数为复制粘贴来的,均未提到这方面的问题。
经过讨论...
以上代码为解决此类问题,目前可以想到的最优解决办法。仅以记录。