使用UITextView或UITextField分类方法解决中文输入问题的bug

来源:互联网 发布:守望先锋max数据不更新 编辑:程序博客网 时间:2024/06/05 02:25

我们曾经遇到这样的一个需求 。 就是我们在使用UITextView或UITextField控件的时候要对输入的个数进行限制。 然而在输入的时候会遇到高光时 控件也在进行个数计算、或者是字符串截串时出现中文等问题 。如下图。 为此我总结出以下的方法解决这个bug。


 


头文件.h

@interface UITextView (Limit)- (NSUInteger)updateTextForLimitLength:(NSUInteger)limitLength;@end@interface UITextField (Limit)@property (nonatomic, assign) NSRange selectedRange;- (NSUInteger)updateTextForLimitLength:(NSUInteger)limitLength;@end

实现文件.m

#import "UITextView+Limit.h"#pragma mark UITextView@interface UITextView (LimitPrivate)@property (nonatomic, strong) NSString *lastText;@property (nonatomic, assign) NSUInteger lastLength;@end@implementation UITextView (LimitPrivate)- (NSString *)lastText{    NSString *object = objc_getAssociatedObject(self, @selector(lastText));    if (object) {        return object;    } else {        return @"";    }}- (void)setLastText:(NSString *)lastText{    objc_setAssociatedObject(self, @selector(lastText), lastText, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (NSUInteger)lastLength{    NSNumber *object = objc_getAssociatedObject(self, @selector(lastLength));    if (object) {        return object.unsignedIntegerValue;    } else {        return 0;    }}- (void)setLastLength:(NSUInteger)lastLength{    NSNumber *object = [NSNumber numberWithUnsignedInteger:lastLength];    objc_setAssociatedObject(self, @selector(lastLength), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end@implementation UITextView (Limit)- (NSUInteger)updateTextForLimitLength:(NSUInteger)limitLength{    NSRange currentRange = self.selectedRange;        //获取高亮部分,如果在变化中是高亮部分在变,忽略    UITextRange *selectedRange = [self markedTextRange];    UITextPosition *pos = [self positionFromPosition:selectedRange.start offset:0];    if (selectedRange && pos) {        return self.lastLength;    }        //截取到最大位置的字符    //这里获取字符串长度要考虑自定义表情,自定义表情使用的是UTF16编码,占两个字节,所以只用length不准    __block NSUInteger textLength = 0;    __block NSMutableString *textContent = [NSMutableString string];    [self.text enumerateSubstringsInRange:NSMakeRange(0, [self.text length])                                  options:NSStringEnumerationByComposedCharacterSequences                               usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {                                   textLength++;                                   [textContent appendString:substring];                               }     ];        if (textLength > limitLength) {        self.text = self.lastText;        self.selectedRange = NSMakeRange(currentRange.location - (textContent.length - self.lastText.length), 0);    } else {        self.lastText = textContent;        self.lastLength = textLength;    }        return self.lastLength;}@end#pragma mark UITextField@interface UITextField (LimitPrivate)@property (nonatomic, strong) NSString *lastText;@property (nonatomic, assign) NSUInteger lastLength;@end@implementation UITextField (LimitPrivate)- (NSString *)lastText{    NSString *object = objc_getAssociatedObject(self, @selector(lastText));    if (object) {        return object;    } else {        return @"";    }}- (void)setLastText:(NSString *)lastText{    objc_setAssociatedObject(self, @selector(lastText), lastText, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (NSUInteger)lastLength{    NSNumber *object = objc_getAssociatedObject(self, @selector(lastLength));    if (object) {        return object.unsignedIntegerValue;    } else {        return 0;    }}- (void)setLastLength:(NSUInteger)lastLength{    NSNumber *object = [NSNumber numberWithUnsignedInteger:lastLength];    objc_setAssociatedObject(self, @selector(lastLength), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end@implementation UITextField (Limit)- (NSRange)selectedRange{    UITextPosition* beginning = self.beginningOfDocument;    UITextRange* selectedRange = self.selectedTextRange;        UITextPosition* selectionStart = selectedRange.start;    UITextPosition* selectionEnd = selectedRange.end;        NSInteger location = [self offsetFromPosition:beginning toPosition:selectionStart];    NSInteger length = [self offsetFromPosition:selectionStart toPosition:selectionEnd];        return NSMakeRange(location, length);}- (void)setSelectedRange:(NSRange)selectedRange{    UITextPosition* beginning = self.beginningOfDocument;        UITextPosition* startPosition = [self positionFromPosition:beginning offset:selectedRange.location];    UITextPosition* endPosition = [self positionFromPosition:beginning offset:selectedRange.location + selectedRange.length];    UITextRange* selectionRange = [self textRangeFromPosition:startPosition toPosition:endPosition];        [self setSelectedTextRange:selectionRange];}- (NSUInteger)updateTextForLimitLength:(NSUInteger)limitLength{    NSRange currentRange = self.selectedRange;        //获取高亮部分,如果在变化中是高亮部分在变,忽略    UITextRange *selectedRange = [self markedTextRange];    UITextPosition *pos = [self positionFromPosition:selectedRange.start offset:0];    if (selectedRange && pos) {        return self.lastLength;    }        //截取到最大位置的字符    //这里获取字符串长度要考虑自定义表情,自定义表情使用的是UTF16编码,占两个字节,所以只用length不准    __block NSUInteger textLength = 0;    __block NSMutableString *textContent = [NSMutableString string];    [self.text enumerateSubstringsInRange:NSMakeRange(0, [self.text length])                                  options:NSStringEnumerationByComposedCharacterSequences                               usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {                                   textLength++;                                   [textContent appendString:substring];                               }     ];        if (textLength > limitLength) {        self.text = self.lastText;        self.selectedRange = NSMakeRange(currentRange.location - (textContent.length - self.lastText.length), 0);    } else {        self.lastText = textContent;        self.lastLength = textLength;    }        return self.lastLength;}@end


0 0
原创粉丝点击