最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS UITextField最大字符數(shù)和字節(jié)數(shù)的限制詳解

 更新時(shí)間:2016年11月30日 08:47:28   投稿:daisy  
在開發(fā)中我們經(jīng)常遇到這樣的需求:在UITextField或者UITextView中限制用戶可以輸入的最大字符數(shù)。但在UITextView , UITextfield 中有很多坑,網(wǎng)上的方法也很多。但是并不是很全面吧,這里全面進(jìn)行了總結(jié),有需要的朋友們可以參考借鑒,下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。

前言

這里我給大家?guī)捉M測試用例可以一試,為啥不好用。

     1、限制10個(gè)字節(jié),輸入2個(gè)Emoj之后是8個(gè)字節(jié)(一個(gè)Emoj是4個(gè)字節(jié)),此時(shí)再輸入一個(gè)中文,看看結(jié)果如何(中文的UTF8占3個(gè)字節(jié))

     2、限制5個(gè)字符,一個(gè)Emoj是2個(gè)字符,其他都是一個(gè)。此時(shí)輸入兩個(gè)Emoj,再輸入中文,然后中文聯(lián)想試試。

就目前的情況來說,看了很多資料,并沒有一個(gè)通用的能限制字符數(shù)和字節(jié)數(shù)的封裝。這里全面進(jìn)行了總結(jié),并進(jìn)行了封裝。歡迎大家下載。

一. 字符限制

1. 錯(cuò)誤方法

常見的這種方法是錯(cuò)誤的,會(huì)導(dǎo)致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;
}

這種限制方法會(huì)導(dǎo)致拼音下出現(xiàn)這種情況,且無法輸入.無法輸入滿5個(gè)字符。在emoj表情也有問題

2. 推薦方法

使用rangeOfComposedCharacterSequencesForRange, 防止在range范圍內(nèi)整詞被截?cái)?/p>

- (void)textFieldDidChange:(UITextField *)textField
{
 NSString *toBeString = textField.text;

 UITextRange *selectedRange = [textField markedTextRange];
 UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
 
 // 沒有高亮選擇的字,則對(duì)已輸入的文字進(jìn)行字?jǐn)?shù)統(tǒng)計(jì)和限制,防止中文被截?cái)?
 if (!position){
 if (toBeString.length > _maxLength){
  //中文和emoj表情存在問題,需要對(duì)此進(jìn)行處理
  NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, _maxLength)];
  textField.text = [toBeString substringWithRange:rangeRange];
 }
 }
}

二. 字節(jié)限制

1. 限制字節(jié)數(shù)

在UTF8中,英文和數(shù)字是1個(gè)字節(jié),漢子是3個(gè)字節(jié),emoji是3或者4個(gè)字節(jié)。這里的難度比上面更大,如果截取失敗,極有可能出現(xiàn)亂碼。這里我們的做法如下

- (void)textFieldDidChange:(UITextField *)textField
{
 NSString *toBeString = textField.text;
 //---字節(jié)處理
 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];
 
 //限制字節(jié)數(shù)
 if ([inputString length] > 0){
 NSInteger len = strlen([inputString UTF8String]);
 if (len > _maxBytesLength){
  return NO;
 }
 else {
  return YES;
 }
 }
 return YES;
}

這里不能只在進(jìn)行限制,在textFieldDidChange中需要對(duì)中文聯(lián)想做處理才行

三. 放棄鍵盤

1. 能拿到uitextfield的時(shí)候用

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

2. 點(diǎn)擊view消失的時(shí)候用

[self.view endEditing:YES];

3. 難以獲取的時(shí)候用

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

或者

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

4.Tableview點(diǎn)擊空白處或者滾動(dòng)時(shí)消失

{
 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];
}

四. 正則表達(dá)式限制

請(qǐng)參考 正則表達(dá)式語法表 ,這里我提供了兩種表達(dá)式給大家參考,一個(gè)Int,一個(gè)無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的鍵盤事件多次回調(diào)問題

1.鍵盤高度遮擋問題

一般出現(xiàn)遮擋的時(shí)候我們用以下代碼,看看當(dāng)前textfield是否在鍵盤下面,在的話算出鍵盤的頂端和textfield的底部的距離,然后做偏移動(dòng)畫

- (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、真機(jī)

如果使用了中文輸入法,注冊(cè)的keyboardWillShow會(huì)回調(diào)兩次。第一次是鍵盤默認(rèn)高度216,第二次則是加了keyboard的導(dǎo)航欄的高度。

2、模擬器

第一次彈出鍵盤沒有問題

打印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;
}

此時(shí)我們?nèi)グ?23旁邊的小圓球會(huì)出現(xiàn)如下的圖:

打印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;
}

鍵盤被遮擋了。

總結(jié):觀察結(jié)果,發(fā)現(xiàn)了這個(gè)規(guī)律,打印一下時(shí)間,還有一個(gè)問題就是,中文鍵盤第一次啟動(dòng)的時(shí)候會(huì)回調(diào)兩次。

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

所以去掉這句話即可

六. 使用封裝的XXTextField

UITextView , UITextfield 中如果有keyboard的時(shí)候,需要一個(gè)自動(dòng)彈起事件,以及彈起之后的content的偏移對(duì)父view的處理。如果每個(gè)頁面都實(shí)現(xiàn)一次會(huì)非常復(fù)雜。這里我們介紹一種自動(dòng)化的處理機(jī)制。在此之前,先介紹一下文字處理框架.最后給大家推薦一下我寫的 XXTextField ,大家也可以在此基礎(chǔ)上自己添加一些正則表達(dá)式。

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中鍵盤遮擋問題

/*
 * 鍵盤要顯示的時(shí)候
 */
- (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];
 }
}

/*
 * 鍵盤要消失的時(shí)候
 */
- (void)hiddenKeyboardWithRect:(CGRect)keyboardRect
     withDuration:(CGFloat)animationDuration{
 _baseTableView.contentInset = UIEdgeInsetsZero;
 _baseTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)各位Android開發(fā)者們能有所幫助,如果有疑問大家可以留言交流。

相關(guān)文章

最新評(píng)論

河东区| 班玛县| 保康县| 无棣县| 临洮县| 余姚市| 独山县| 鄯善县| 大厂| 三门县| 贵德县| 灌云县| 全南县| 都江堰市| 抚宁县| 平定县| 金秀| 竹北市| 西宁市| 阿勒泰市| 无锡市| 土默特右旗| 高邮市| 崇明县| 定远县| 夏津县| 绥化市| 哈巴河县| 木里| 仲巴县| 平安县| 灵山县| 梨树县| 栾城县| 蓬溪县| 宜丰县| 黄山市| 桃园市| 岳阳市| 秦皇岛市| 乌鲁木齐市|