? ? ? ? iOS遇到輸入框輸入時,藍色的拼音文字也是屬于textField的內容枷遂,一般的textField.text的length時會算進去樱衷,所以這里不太好判斷,要是如果遇到了強迫癥的產品經理一定要你在輸入文字達到最大長度時酒唉,連拼音都不能輸入矩桂,那就麻煩了。
? ? ? ?不過別慌痪伦,這里有教程侄榴,保證你能滿足需求阔籽,本文是在三方基礎上改的 <RestrictionInput>, 末尾回復上該源碼,可直接食用牲蜀,如果對你有幫助點個贊或者收藏下
#import "GroupNameViewCtrl.h"
#import "RestrictionInput.h"
@interface GroupNameViewCtrl () <UITextFieldDelegate>
{
NSInteger MAX_INPUT_LENGTH; // 中文字數限制字數笆制,轉化成英文兩倍
}
@property (nonatomic, strong) UIView *textBaseview;
@property (nonatomic, strong) UITextField *txtField;
@property (nonatomic, copy) NSString *currentText;
@property (nonatomic, assign) BOOL isStop; // 字數達到最大時否停止輸入
@end
@implementation GroupNameViewCtrl
- (void)viewDidLoad {
[super viewDidLoad];
_isStop = NO;
MAX_INPUT_LENGTH = 20;
[self setNavi];
[self setUI];
if (!_isMaster) {
self.rightBtn.hidden = YES;
self.txtField.userInteractionEnabled = NO;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange:) name:UITextFieldTextDidChangeNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setNavi {
[self.rightBtn setTitle:GET_LANGUAGE_KEY(@"OK") forState:UIControlStateNormal];
[self.rightBtn setImage:nil forState:UIControlStateNormal];
self.rightBtn.titleLabel.font = FONT_F3;
self.rightBtn.titleLabel.adjustsFontSizeToFitWidth = YES;
}
- (void)setUI {
[self.view addSubview:self.textBaseview];
[self.textBaseview addSubview:self.txtField];
UIButton *btnDelete = [[UIButton alloc] init];
[btnDelete setImage:[UIImage imageNamed:@"clear"] forState:UIControlStateNormal];
[btnDelete addTarget:self action:@selector(btnDeleteAction:) forControlEvents:UIControlEventTouchUpInside];
[self.textBaseview addSubview:btnDelete];
[self.textBaseview mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.naviView.mas_bottom).offset(12);
make.left.right.equalTo(self.view);
make.height.equalTo(49);
}];
[self.txtField mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.textBaseview);
make.left.equalTo(self.textBaseview).offset(15);
make.right.equalTo(self.textBaseview).offset(-40);
}];
[btnDelete mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.textBaseview).offset(16);
make.centerY.equalTo(self.textBaseview);
}];
}
/*********** 正 文 開 始 ***********/
#pragma mark - notification
- (void)textFieldChange:(NSNotification *)noti {
UITextField *txtView = (UITextField *)noti.object;
//判斷輸入(不能輸入特殊字符)
[RestrictionInput restrictionInputTextField:txtView maxNumber:MAX_INPUT_LENGTH*2+1 showErrorMessage:nil];
NSString *toBeString = txtView.text;
NSString *lang = [[txtView textInputMode] primaryLanguage];
if([lang isEqualToString:@"zh-Hans"]) { //簡體中文輸入,包括簡體拼音涣达,健體五筆在辆,簡體手寫
UITextRange *selectedRange = [txtView markedTextRange];
UITextPosition *position = [txtView positionFromPosition:selectedRange.start offset:0];
if (!position){//非高亮
NSInteger length = [Utils getToLength:toBeString];
if ((MAX_INPUT_LENGTH-length/2) > 0) {
_isStop = NO;
} else {
_isStop = YES;
}
}
}else{//中文輸入法以外
NSInteger length = [Utils getToLength:toBeString];
if ((MAX_INPUT_LENGTH-length/2) > 0) {
_isStop = NO;
} else {
_isStop = YES;
}
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([string isEqualToString:@""]) {
return YES;
}
if ([string isEqualToString:@"\n"]) {
[textField resignFirstResponder];
return NO;
}
if (_isStop) {
return NO;
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[_txtField resignFirstResponder];
return YES;
}
/*********** 正 文 結 束 ***********/
#pragma mark - event
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[_txtField resignFirstResponder];
}
- (void)clickLeftButton:(UIButton *)sender {
[_txtField resignFirstResponder];
_currentText = [self.txtField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([_currentText isEqualToString:_model.title]) {
[self.navigationController popViewControllerAnimated:YES];
return;
}
UIAlertController *alert = [UIAlertController alertControllerWithTitle:GET_LANGUAGE_KEY(@"giveupModify") message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:GET_LANGUAGE_KEY(@"cancel") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction *ok = [UIAlertAction actionWithTitle:GET_LANGUAGE_KEY(@"OK") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self.navigationController popViewControllerAnimated:YES];
}];
[alert addAction:cancel];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)clickRightButton:(UIButton *)sender {
[_txtField resignFirstResponder];
// 去掉首位空格
_currentText = [self.txtField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// 保存網絡請求吧啦吧啦吧啦
}
- (void)btnDeleteAction:(UIButton *)sender {
_txtField.text = nil;
}
#pragma mark - setter and getter
- (UIView *)textBaseview {
if (!_textBaseview) {
_textBaseview = [[UIView alloc] init];
_textBaseview.backgroundColor = COLOR_B7;
}
return _textBaseview;
}
- (UITextField *)txtField {
if (!_txtField) {
_txtField = [[UITextField alloc] init];
_txtField.textColor = COLOR_B1;
_txtField.font = FONT_F4;
_txtField.returnKeyType = UIReturnKeyDone;
_txtField.delegate = self;
_txtField.text = _model.title;
_txtField.placeholder = GET_LANGUAGE_KEY(@"inputGroupName");
// 防止初始化的時候就達到最大值還能輸的情況
NSInteger length = [Utils getToLength:_txtField.text];
if ((MAX_INPUT_LENGTH-length/2) > 0) {
_isStop = NO;
} else {
_isStop = YES;
}
}
return _txtField;
}
@end
// RestrictionInput.h
#import <Foundation/Foundation.h>
@interface RestrictionInput : NSObject
+ (void)restrictionInputTextField:(UITextField *)inputClass maxNumber:(NSInteger)maxNumber showErrorMessage:(NSString *)errorMessage;
+ (void)restrictionInputTextView:(UITextView *)inputClass maxNumber:(NSInteger)maxNumber showErrorMessage:(NSString *)errorMessage checkChar:(BOOL)checkChar;
+ (BOOL)isInputRuleAndBlank:(NSString *)str regular:(NSString *)regular;
@end
// RestrictionInput.m
#import "RestrictionInput.h"
@implementation RestrictionInput
+ (void)restrictionInputTextField:(UITextField *)inputClass maxNumber:(NSInteger)maxNumber showErrorMessage:(NSString *)errorMessage
{
NSString *toBeString = inputClass.text;
if (![self isInputRuleAndBlank:toBeString regular:REGULAR_EXPRESSION]) {
inputClass.text = [self disable_emoji:toBeString];
return;
}
NSString *lang = [[inputClass textInputMode] primaryLanguage]; // 獲取當前鍵盤輸入模式
if([lang isEqualToString:@"zh-Hans"]) { //簡體中文輸入,第三方輸入法(搜狗)所有模式下都會顯示“zh-Hans”
UITextRange *selectedRange = [inputClass markedTextRange];
//獲取高亮部分
UITextPosition *position = [inputClass positionFromPosition:selectedRange.start offset:0];
//沒有高亮選擇的字,則對已輸入的文字進行字數統(tǒng)計和限制
if(!position) {
NSString *getStr = [self getSubString:toBeString maxNumber:maxNumber];
if(getStr && getStr.length > 0) {
inputClass.text = getStr;
[Utils showToastMessage:errorMessage];
}
}
} else{
NSString *getStr = [self getSubString:toBeString maxNumber:maxNumber];
if(getStr && getStr.length > 0) {
inputClass.text= getStr;
}
}
}
+ (void)restrictionInputTextView:(UITextView *)inputClass maxNumber:(NSInteger)maxNumber showErrorMessage:(NSString *)errorMessage checkChar:(BOOL)checkChar
{
NSString *toBeString = inputClass.text;
if (checkChar) {
if (![self isInputRuleAndBlank:toBeString regular:REGULAR_EXPRESSION]) {
inputClass.text = [self disable_emoji:toBeString];
return;
}
}
NSString *lang = [[inputClass textInputMode] primaryLanguage]; // 獲取當前鍵盤輸入模式
if([lang isEqualToString:@"zh-Hans"]) { //簡體中文輸入,第三方輸入法(搜狗)所有模式下都會顯示“zh-Hans”
UITextRange *selectedRange = [inputClass markedTextRange];
//獲取高亮部分
UITextPosition *position = [inputClass positionFromPosition:selectedRange.start offset:0];
//沒有高亮選擇的字度苔,則對已輸入的文字進行字數統(tǒng)計和限制
if(!position) {
NSString *getStr = [self getSubString:toBeString maxNumber:maxNumber];
if(getStr && getStr.length > 0) {
inputClass.text = getStr;
[Utils showToastMessage:errorMessage];
}
}
} else{
NSString *getStr = [self getSubString:toBeString maxNumber:maxNumber];
if(getStr && getStr.length > 0) {
inputClass.text= getStr;
[Utils showToastMessage:errorMessage];
}
}
}
/**
* 獲得 kMaxLength長度的字符
*/
+ (NSString *)getSubString:(NSString*)string maxNumber:(NSInteger)maxNumber
{
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData* data = [string dataUsingEncoding:encoding];
NSInteger length = [data length];
if (length > maxNumber) {
NSData *data1 = [data subdataWithRange:NSMakeRange(0, maxNumber)];
NSString *content = [[NSString alloc] initWithData:data1 encoding:encoding];//【注意4】:當截取kMaxLength長度字符時把中文字符截斷返回的content會是nil
if (!content || content.length == 0) {
data1 = [data subdataWithRange:NSMakeRange(0, maxNumber - 1)];
content = [[NSString alloc] initWithData:data1 encoding:encoding];
}
return content;
}
return nil;
}
/**
* 字母匆篓、數字、中文正則判斷(不包括空格)
*/
+ (BOOL)isInputRuleNotBlank:(NSString *)str {
NSString *pattern = @"^[????????\a-zA-Z\u4E00-\u9FA5\\d]*$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
BOOL isMatch = [pred evaluateWithObject:str];
return isMatch;
}
/**
* 字母寇窑、數字鸦概、中文正則判斷(包括空格)【注意3】
*/
+ (BOOL)isInputRuleAndBlank:(NSString *)str regular:(NSString *)regular {
//九宮格無法輸入解決需要加上正則 \????????
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regular];
BOOL isMatch = [pred evaluateWithObject:str];
return isMatch;
}
+ (NSString *)disable_emoji:(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 = [regex stringByReplacingMatchesInString:text
options:0
range:NSMakeRange(0, [text length])
withTemplate:@""];
return modifiedString;
}
@end