手机
当前位置:查字典教程网 >编程开发 >IOS开发 >iOS UITextField最大字符数和字节数的限制详解
iOS UITextField最大字符数和字节数的限制详解
摘要:前言这里我给大家几组测试用例可以一试,为啥不好用。1、限制10个字节,输入2个Emoj之后是8个字节(一个Emoj是4个字节),此时再输入一...

前言

这里我给大家几组测试用例可以一试,为啥不好用。

1、限制10个字节,输入2个Emoj之后是8个字节(一个Emoj是4个字节),此时再输入一个中文,看看结果如何(中文的UTF8占3个字节)

2、限制5个字符,一个Emoj是2个字符,其他都是一个。此时输入两个Emoj,再输入中文,然后中文联想试试。

就目前的情况来说,看了很多资料,并没有一个通用的能限制字符数和字节数的封装。这里全面进行了总结,并进行了封装。欢迎大家下载。

一. 字符限制

1. 错误方法

常见的这种方法是错误的,会导致Emoj表情的截取问题

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if(range.length + range.location > textField.text.length) { return NO; } NSUInteger newLength = [textField.text length] + [string length] - range.length; return newLength <= 5; }

这种限制方法会导致拼音下出现这种情况,且无法输入.无法输入满5个字符。在emoj表情也有问题

iOS UITextField最大字符数和字节数的限制详解1

2. 推荐方法

使用rangeOfComposedCharacterSequencesForRange, 防止在range范围内整词被截断

- (void)textFieldDidChange:(UITextField *)textField { NSString *toBeString = textField.text; UITextRange *selectedRange = [textField markedTextRange]; UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0]; // 没有高亮选择的字,则对已输入的文字进行字数统计和限制,防止中文被截断 if (!position){ if (toBeString.length > _maxLength){ //中文和emoj表情存在问题,需要对此进行处理 NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, _maxLength)]; textField.text = [toBeString substringWithRange:rangeRange]; } } }

iOS UITextField最大字符数和字节数的限制详解2

二. 字节限制

1. 限制字节数

在UTF8中,英文和数字是1个字节,汉子是3个字节,emoji是3或者4个字节。这里的难度比上面更大,如果截取失败,极有可能出现乱码。这里我们的做法如下

- (void)textFieldDidChange:(UITextField *)textField { NSString *toBeString = textField.text; //---字节处理 NSInteger bytesCount = strlen([textField.text UTF8String]); if (bytesCount > _maxBytesLength) { NSString *content = [textField.text subStrWithUtf8Len:(int)_maxBytesLength]; textField.text = content; } } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ NSString * inputString = [textField.text stringByReplacingCharactersInRange:range withString:string]; //限制字节数 if ([inputString length] > 0){ NSInteger len = strlen([inputString UTF8String]); if (len > _maxBytesLength){ return NO; } else { return YES; } } return YES; }

这里不能只在进行限制,在textFieldDidChange中需要对中文联想做处理才行

三. 放弃键盘

1. 能拿到uitextfield的时候用

- (BOOL)textFieldShouldReturn:(UITextField *)textField { return [textField resignFirstResponder]; }

2. 点击view消失的时候用

[self.view endEditing:YES];

3. 难以获取的时候用

[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

或者

[[[UIApplication sharedApplication] keyWindow] endEditing:YES];

4.Tableview点击空白处或者滚动时消失

{ UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fingerTapped:)]; [self.view addGestureRecognizer:singleTap]; } #pragma mark- 键盘消失 -(void)fingerTapped:(UITapGestureRecognizer *)gestureRecognizer{ [self.view endEditing:YES]; } -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ [self.view endEditing:YES]; }

四. 正则表达式限制

请参考 正则表达式语法表 ,这里我提供了两种表达式给大家参考,一个Int,一个无unsignedInt

-(BOOL) isTextFieldMatchWithRegularExpression:(NSString *)exporession{ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",exporession]; return [predicate evaluateWithObject:self]; } -(BOOL) isTextFieldIntValue{ return [self isTextFieldMatchWithRegularExpression:@"[-]{0,1}[0-9]*"]; } -(BOOL) isTextFieldUnsignedIntValue{ return [self isTextFieldMatchWithRegularExpression:@"[0-9]+"]; }

五. UITextfield的键盘事件多次回调问题

1.键盘高度遮挡问题

一般出现遮挡的时候我们用以下代码,看看当前textfield是否在键盘下面,在的话算出键盘的顶端和textfield的底部的距离,然后做偏移动画

- (void)keyboardWillShow:(NSNotification *)notification { NSDictionary *userInfo = [notification userInfo]; NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]; CGRect keyboardRect = [aValue CGRectValue]; keyboardRect = [self.view convertRect:keyboardRect fromView:nil]; CGFloat keyboardTop = keyboardRect.origin.y; CGFloat offset = self.normalTextField.frame.size.height + self.normalTextField.frame.origin.y - keyboardTop; NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey]; NSTimeInterval animationDuration; [animationDurationValue getValue:&animationDuration]; if(offset > 0){ // Animate the resize of the text view's frame in sync with the keyboard's appearance. [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:animationDuration]; CGRect rect = CGRectMake(0.0f, -offset,self.view.frame.size.width,self.view.frame.size.height); self.view.frame = rect; [UIView commitAnimations]; } }

1、真机

如果使用了中文输入法,注册的keyboardWillShow会回调两次。第一次是键盘默认高度216,第二次则是加了keyboard的导航栏的高度。

2、模拟器

第一次弹出键盘没有问题

iOS UITextField最大字符数和字节数的限制详解3

打印userinfo:

(lldb) po userInfo { UIKeyboardAnimationCurveUserInfoKey = 7; UIKeyboardAnimationDurationUserInfoKey = "0.25"; UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {414, 226}}"; UIKeyboardCenterBeginUserInfoKey = "NSPoint: {207, 849}"; UIKeyboardCenterEndUserInfoKey = "NSPoint: {207, 623}"; UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 736}, {414, 226}}"; UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 510}, {414, 226}}"; UIKeyboardIsLocalUserInfoKey = 1; }

此时我们去按123旁边的小圆球会出现如下的图:

iOS UITextField最大字符数和字节数的限制详解4

打印userinfo:

(lldb) po userInfo { UIKeyboardAnimationCurveUserInfoKey = 7; UIKeyboardAnimationDurationUserInfoKey = "0.25"; UIKeyboardBoundsUserInfoKey = "NSRect: {{0, 0}, {414, 271}}"; UIKeyboardCenterBeginUserInfoKey = "NSPoint: {207, 623}"; UIKeyboardCenterEndUserInfoKey = "NSPoint: {207, 600.5}"; UIKeyboardFrameBeginUserInfoKey = "NSRect: {{0, 510}, {414, 226}}"; UIKeyboardFrameEndUserInfoKey = "NSRect: {{0, 465}, {414, 271}}"; UIKeyboardIsLocalUserInfoKey = 1; }

键盘被遮挡了。

总结:观察结果,发现了这个规律,打印一下时间,还有一个问题就是,中文键盘第一次启动的时候会回调两次。

keyboardRect = [self.view convertRect:keyboardRect fromView:nil];

所以去掉这句话即可

六. 使用封装的XXTextField

UITextView , UITextfield 中如果有keyboard的时候,需要一个自动弹起事件,以及弹起之后的content的偏移对父view的处理。如果每个页面都实现一次会非常复杂。这里我们介绍一种自动化的处理机制。在此之前,先介绍一下文字处理框架.最后给大家推荐一下我写的 XXTextField ,大家也可以在此基础上自己添加一些正则表达式。

1.解决uiview中的textfield 遮挡问题

_textfieldName.keyboardType = UIKeyboardTypeDefault; _textfieldName.inputType = XXTextFieldTypeOnlyInt; _textfieldName.maxLength = 5; _textfieldPwd.inputType = XXTextFieldTypeForbidEmoj; #import "XXKeyboardManager.h" @interface XXCorrectVC ()<XXKeyboardManagerShowHiddenNotificationDelegate> @end @implementation XXCorrectVC - (void)viewDidLoad { [super viewDidLoad]; [[XXKeyboardManager sharedInstance] setDelegate:self]; // Do any additional setup after loading the view from its nib. } #pragma mark- KeyBoardShow/Hidden - (void)showKeyboardWithRect:(CGRect)keyboardRect withDuration:(CGFloat)animationDuration { CGFloat offset = self.textFieldCorrect.frame.size.height + self.textFieldCorrect.frame.origin.y - keyboardRect.origin.y; if(offset < 0){ return; } [UIView animateWithDuration:animationDuration delay:0.f options:UIViewAnimationOptionCurveEaseInOut animations:^{ CGRect rect = CGRectMake(0.0f, -offset,self.view.frame.size.width,self.view.frame.size.height); self.view.frame = rect; } completion:^(BOOL finished) { }]; } - (void)hiddenKeyboardWithRect:(CGRect)keyboardRect withDuration:(CGFloat)animationDuration { [UIView animateWithDuration:animationDuration delay:0.f options:UIViewAnimationOptionCurveEaseInOut animations:^{ self.textFieldCorrect.frame = self.view.bounds; } completion:^(BOOL finished) { }]; } @end

2.解决uitableview中键盘遮挡问题

/* * 键盘要显示的时候 */ - (void)showKeyboardWithRect:(CGRect)keyboardRect withDuration:(CGFloat)animationDuration{ CGSize kbSize = keyboardRect.size; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); _baseTableView.contentInset = contentInsets; _baseTableView.scrollIndicatorInsets = contentInsets; // If active text field is hidden by keyboard, scroll it so it's visible // Your app might not need or want this behavior. CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; if (!CGRectContainsPoint(aRect, _activeCell.frame.origin) ) { [_baseTableView scrollRectToVisible:_activeCell.frame animated:YES]; } } /* * 键盘要消失的时候 */ - (void)hiddenKeyboardWithRect:(CGRect)keyboardRect withDuration:(CGFloat)animationDuration{ _baseTableView.contentInset = UIEdgeInsetsZero; _baseTableView.scrollIndicatorInsets = UIEdgeInsetsZero; }

总结

以上就是这篇文章的全部内容了,希望本文的内容对各位Android开发者们能有所帮助,如果有疑问大家可以留言交流。

【iOS UITextField最大字符数和字节数的限制详解】相关文章:

IOS改变UISearchBar中搜索框的高度

iOS开发之UIPickerView实现城市选择器的步骤详解

Unity iOS混合开发界面切换思路解析

iOS中UITextField 使用全面解析

iOS 雷达效果实例详解

iOS功能实现之列表的横向刷新加载

使用UITextField限制只可输入中,英文,数字的方法

IOS textField限制字节长度

IOS UI学习教程之设置UITextField各种属性

iOS应用中UILabel文字显示效果的常用设置总结

精品推荐
分类导航