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

2025-05-29 0 18

前言

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

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

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

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

一. 字符限制

1. 错误方法

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

?

1

2

3

4

5

6

7

8

9

10
- (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最大字符数和字节数的限制详解

2. 推荐方法

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
- (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最大字符数和字节数的限制详解

二. 字节限制

1. 限制字节数

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27
- (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的时候用

?

1

2

3

4
- (bool)textfieldshouldreturn:(uitextfield *)textfield

{

return [textfield resignfirstresponder];

}

2. 点击view消失的时候用

?

1
[self.view endediting:yes];

3. 难以获取的时候用

?

1
[[uiapplication sharedapplication] sendaction:@selector(resignfirstresponder) to:nil from:nil forevent:nil];

或者

?

1
[[[uiapplication sharedapplication] keywindow] endediting:yes];

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

?

1

2

3

4

5

6

7

8

9

10

11

12
{

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

?

1

2

3

4

5

6

7

8

9

10

11
-(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的底部的距离,然后做偏移动画

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26
- (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最大字符数和字节数的限制详解

打印userinfo:

?

1

2

3

4

5

6

7

8

9

10

11
(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最大字符数和字节数的限制详解

打印userinfo:

?

1

2

3

4

5

6

7

8

9

10

11
(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;

}

键盘被遮挡了。

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

?

1
keyboardrect = [self.view convertrect:keyboardrect fromview:nil];

所以去掉这句话即可

六. 使用封装的xxtextfield

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

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45
_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中键盘遮挡问题

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30
/*

* 键盘要显示的时候

*/

- (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开发者们能有所帮助,如果有疑问大家可以留言交流。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 iOS UITextField最大字符数和字节数的限制详解 https://www.kuaiidc.com/92499.html

相关文章

发表评论
暂无评论