超簡單- 限制輸入長度

目錄


一、效果圖

二、使用
@interface ViewController ()

@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UITextView *textView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.textField setValue:@(3) forKey:@"input_limit_length"];
    [self.textView setValue:@(5) forKey:@"input_limit_length"];
}

- (IBAction)onSubmitClick:(id)sender {
    NSLog(@"self.textField.text = %@", self.textField.text);
    NSLog(@"self.textView.text = %@", self.textView.text);
}

@end

三、LimitInput類源碼

不想看代碼的直接新建一個類,繼承自NSObject,把下面代碼複製即可

#import "LimitInput.h"
#import <objc/runtime.h>

@implementation UITextField(Limit)

- (id)valueForUndefinedKey:(NSString *)key {
    if ([key isEqualToString:PROPERTY_NAME]) {
        return objc_getAssociatedObject(self, key.UTF8String);
    }
    return nil;
}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    if ([key isEqualToString:PROPERTY_NAME]) {
        objc_setAssociatedObject(self, key.UTF8String, value, OBJC_ASSOCIATION_RETAIN);
    }
}

@end


@implementation UITextView(Limit)

- (id)valueForUndefinedKey:(NSString *)key {
    if ([key isEqualToString:PROPERTY_NAME]) {
        return objc_getAssociatedObject(self, key.UTF8String);
    }
    return nil;
}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    if ([key isEqualToString:PROPERTY_NAME]) {
        objc_setAssociatedObject(self, key.UTF8String, value, OBJC_ASSOCIATION_RETAIN);
    }
}

@end


@implementation LimitInput

#pragma mark - life cycle
+ (void)load {
    [super load];
    [LimitInput sharedInstance];
}

+ (LimitInput *)sharedInstance {
    static LimitInput *limitInput;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        limitInput = [[LimitInput alloc] init];
        limitInput.enableLimitCount = YES;
    });
    return limitInput;
}

- (instancetype)init {
    if (self = [super init]) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(textFieldViewDidChange:)
                                                     name:UITextFieldTextDidChangeNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(textFieldViewDidEndEditing:)
                                                     name:UITextFieldTextDidEndEditingNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(textViewDidChange:)
                                                     name:UITextViewTextDidChangeNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(textViewDidEndEditing:)
                                                     name:UITextViewTextDidEndEditingNotification
                                                   object:nil];
    }
    return self;
}

#pragma mark - UITextFieldNotification
- (void)textFieldViewDidEndEditing:(NSNotification *)notification {
    if (!self.enableLimitCount) {
        return;
    }
    
    NSString *textFieldClass = NSStringFromClass([notification.object class]);
    if ([textFieldClass isEqualToString:@"RCUITextField"]) {
        return;
    }
        
    UITextField *textField = (UITextField *)notification.object;
    NSString *trimmingText = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    if(trimmingText.length == 0) {
        textField.text = @"";
    }
}

- (void)textFieldViewDidChange:(NSNotification *)notification {
    if (!self.enableLimitCount) {
        return;
    }
    
    NSString *textFieldClass = NSStringFromClass([notification.object class]);
    if ([textFieldClass isEqualToString:@"RCUITextField"] || [textFieldClass isEqualToString:@"_UIAlertControllerTextField"]) {
        return;
    }
    UITextField *textField = (UITextField *)notification.object;
    
    /**
     禁用表情符號(直接打開註釋即可)
     
     NSString *inputText = [self disableEmoji:textField.text];
     if(inputText != nil) {
         // 含有表情符號,替換輸入域內容
         textField.text = inputText;
     }
     
     */
    NSNumber *number = [textField valueForKey:PROPERTY_NAME];
    if (number && textField.text.length > [number integerValue] && textField.markedTextRange == nil) {
        // 處理Emoji表情被截取,非法字符"A"問題
        NSRange range = [textField.text rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, [number integerValue])];
        textField.text = [textField.text substringWithRange:range];
    }
}


#pragma mark - UITextViewNotification
- (void)textViewDidEndEditing:(NSNotification *)notification {
    if (!self.enableLimitCount) {
        return;
    }
    
    NSString *textViewClass = NSStringFromClass([notification.object class]);
    if ([textViewClass isEqualToString:@"RCTextView"]) {
        return;
    }
    
    UITextView *textView = (UITextView *)notification.object;
    NSString *trimmingText = [textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    if(trimmingText.length == 0) {
        textView.text = @"";
    }
}

- (void)textViewDidChange:(NSNotification *)notificaiton {
    if (!self.enableLimitCount) {
        return;
    }
    
    NSString *textViewClass = NSStringFromClass([notificaiton.object class]);
    if ([textViewClass isEqualToString:@"RCTextView"]) {
        return;
    }
    UITextView *textView = (UITextView *)notificaiton.object;
    
    /**
     禁用表情符號(直接打開註釋即可)
     
     NSString *inputText = [self disableEmoji:textView.text];
     if(inputText != nil) {
         textView.text = inputText;
     }
     */
    NSNumber *number = [textView valueForKey:PROPERTY_NAME];
    if (number && textView.text.length > [number integerValue] && textView.markedTextRange == nil) {
        // 處理Emoji表情被截取,非法字符"A"問題
        NSRange range = [textView.text rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, [number integerValue])];
        textView.text = [textView.text substringWithRange:range];
    }
}

/// 替換掉表情符號:不含有表情符號時返回nil,不做處理;返回非nil字符串時,需要將返回串替換輸入域內容
- (NSString *)disableEmoji:(NSString *)text {
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]"
                                                                           options:NSRegularExpressionCaseInsensitive error:nil];
    NSString *modifiedString= text;
    if([regex numberOfMatchesInString:text
                              options:0
                                range:NSMakeRange(0, text.length)] > 0) {
        modifiedString = [regex stringByReplacingMatchesInString:text
                                                         options:0
                                                           range:NSMakeRange(0, [text length])
                                                    withTemplate:@""];
        return modifiedString;
    } else {
        return nil;
    }
}

@end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章