欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UITextFiled,UITextView限制文本输入长度

程序员文章站 2022-04-06 11:45:18
...

很多时候需要简单的限制一下文本输入框的文本长度.写多了类似的代码之后,想把它封装一下一劳永逸.封装后将一行代码搞定文本输入长度限制.
封装一个UITextField的分类:

@interface UITextField (XQHelper)

//限制UITextField的输入字数.0表示无限制.
@property (nonatomic, assign) NSInteger xq_limitTextLength;

@end
@implementation UITextField (XQHelper)

- (NSInteger)xq_limitTextLength
{
    NSNumber *limit = objc_getAssociatedObject(self, @selector(xq_limitTextLength));
    return limit.integerValue;
}

- (void)setXq_limitTextLength:(NSInteger)xq_limitTextLength
{
    objc_setAssociatedObject(self, @selector(xq_limitTextLength), @(xq_limitTextLength), OBJC_ASSOCIATION_ASSIGN);
    
    [self removeTarget:self action:@selector(textFieldTextDidChanged:) forControlEvents:UIControlEventEditingChanged];
    [self addTarget:self action:@selector(textFieldTextDidChanged:) forControlEvents:UIControlEventEditingChanged];
}

- (void)textFieldTextDidChanged:(UITextField *)textField
{
    if (self.xq_limitTextLength <= 0) {
        return;
    }
    
    NSString *contentText = textField.text;
    //防止系统中文键盘输入bug
    // 获取高亮内容的范围
    UITextRange *selectedRange = [textField markedTextRange];
    // 获取高亮内容的长度
    NSInteger markedTextLength = [textField offsetFromPosition:selectedRange.start toPosition:selectedRange.end];
    // 没有高亮内容时,对已输入的文字进行操作
    if (markedTextLength == 0) {
        if (contentText.length > self.xq_limitTextLength) {
            // 此方法用于在字符串的一个range范围内,返回此range范围内完整的字符串的range.(eg:????)
            NSRange rangeRange = [contentText rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, self.xq_limitTextLength)];
            NSString *rsStr = [contentText substringWithRange:rangeRange];
            textField.text = rsStr;
        }
    }
}

@end

使用的时候就只需要设置textField.xq_limitTextLength = 10;就OK了,当输入超过10个字符时,将不能够再输入.

UITextView的分类:

@interface UITextView (XQHelper)

//限制UITextView的输入字数.0表示无限制.
@property (nonatomic, assign) NSInteger xq_limitTextLength;

@end

实现:

@implementation UITextView (XQHelper)

- (NSInteger)xq_limitTextLength
{
    NSNumber *limit = objc_getAssociatedObject(self, @selector(xq_limitTextLength));
    return limit.integerValue;
}

- (void)setXq_limitTextLength:(NSInteger)xq_limitTextLength
{
    objc_setAssociatedObject(self, @selector(xq_limitTextLength), @(xq_limitTextLength), OBJC_ASSOCIATION_ASSIGN);
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:self];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewTextDidChanged:) name:UITextViewTextDidChangeNotification object:self];
}

- (void)textViewTextDidChanged:(NSNotification *)notify
{
    if (self.xq_limitTextLength <= 0) {
        return;
    }
    
    UITextView *textView = notify.object;
    
    UITextRange *selectedRange = [textView markedTextRange];
    //获取高亮部分
    UITextPosition *pos = [textView positionFromPosition:selectedRange.start offset:0];
    
    //如果在变化中是高亮部分在变,就不要计算字符了.防止系统中文键盘输入bug
    if (selectedRange && pos) {
        return;
    }
    
    NSRange selection = textView.selectedRange;
    
    NSInteger realLength = textView.text.length; //实际总长度
    
    NSString *headText = [textView.text substringToIndex:selection.location]; //光标前的文本
    NSString *tailText = [textView.text substringFromIndex:selection.location]; //光标后的文本
    
    NSInteger restLength = self.xq_limitTextLength - tailText.length; //光标后允许输入的文本长度
    
    if (realLength > self.xq_limitTextLength) {
        NSString *subHeadText = [headText substringToIndex:restLength];
        textView.text = [subHeadText stringByAppendingString:tailText];
        [textView setSelectedRange:NSMakeRange(restLength, 0)];
    }
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:self];
}

@end

使用:textView.xq_limitTextLength = 10;
其中在系统中文键盘输入时,因为输入联想的原因,限制时需要做一些判断.
参考:
iOS UITextField限制字符长度