欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS 输入框限制输入字节数

程序员文章站 2022-04-15 10:43:09
iOS中限制输入框文字长度的方法有好多,百度一下,最常用的是这种: 但是这种方法有bug,当输入最后一个汉字的时候,只能输入拼音不能变成汉字。 经过仔细的搜索之后会发现另一中方法: 这种方法没有前面说的那种bug,会截取指定长度字符串,但是如果是中英文混合输入的话就没办法根据字节数计算对应的字符串长 ......

ios中限制输入框文字长度的方法有好多,百度一下,最常用的是这种:

- (bool)textfield:(uitextfield *)textfield shouldchangecharactersinrange:(nsrange)range replacementstring:(nsstring *)string {
    if ([textfield isequal:self.nametextfield]) {
        nsstring *whole = [nsstring stringwithformat:@"%@%@",textfield.text, string];
        if (range.length == 1 && string.length == 0) {
            return yes;
        }
        if ([whole datausingencoding:nsutf8stringencoding].length > 14) {
            [textfield resignfirstresponder];
            make_toast_top(localizestring(@"namelimit"));
            return no;
        }
    }
    return yes;
}

但是这种方法有bug,当输入最后一个汉字的时候,只能输入拼音不能变成汉字。

经过仔细的搜索之后会发现另一中方法:

    [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(textfielddidchange:) name:uitextfieldtextdidchangenotification object:self.nametextfield];
- (void)textfielddidchange:(nsnotification *)noti {
    nsstring *language = [[uitextinputmode currentinputmode] primarylanguage];
    nsstring *string = self.nametextfield.text;
    nsdata *data = [string datausingencoding:nsutf8stringencoding];
    if ([language rangeofstring:@"zh-hans"].length != 0 || [language rangeofstring:@"zh-hant"].length != 0) {
        uitextrange *selectedrange = self.nametextfield.markedtextrange;
        uitextposition *position = [self.nametextfield positionfromposition:selectedrange.start offset:0];
        if (!position) {
            if (data.length > 14) {
                self.nametextfield.text = [string substringtoindex:14];
                [self.nametextfield resignfirstresponder];
                make_toast_top(localizestring(@"namelimit"));
            }
        } else {

        }
    } else {
        if ([self.nametextfield.text datausingencoding:nsutf8stringencoding].length > 14) {
            [self.nametextfield resignfirstresponder];
            make_toast_top(localizestring(@"namelimit"));
        }
    }
}

这种方法没有前面说的那种bug,会截取指定长度字符串,但是如果是中英文混合输入的话就没办法根据字节数计算对应的字符串长度,我们希望超过指定字节数时,截取到最后一次输入之前的长度。

可以将上面两种方法结合起来来实现我们的需求:

- (bool)textfield:(uitextfield *)textfield shouldchangecharactersinrange:(nsrange)range replacementstring:(nsstring *)string {
    if (range.length != 0) { self.lastinputstringrange = range; }
    return yes;
}
- (void)textfielddidchange:(nsnotification *)noti {
    nsstring *language = [[uitextinputmode currentinputmode] primarylanguage];
    nsstring *string = self.nametextfield.text;
    nsdata *data = [string datausingencoding:nsutf8stringencoding];
    if ([language rangeofstring:@"zh-hans"].length != 0 || [language rangeofstring:@"zh-hant"].length != 0) {
        uitextrange *selectedrange = self.nametextfield.markedtextrange;
        uitextposition *position = [self.nametextfield positionfromposition:selectedrange.start offset:0];
        if (!position) {
            if (data.length > 14) {
                self.nametextfield.text = [string substringtoindex:self.lastinputstringrange.location];
                [self.nametextfield resignfirstresponder];
                make_toast_top(localizestring(@"namelimit"));
            }
        } else {

        }
    } else {
        if ([self.nametextfield.text datausingencoding:nsutf8stringencoding].length > 14) {
            self.nametextfield.text = [string substringtoindex:14];
            [self.nametextfield resignfirstresponder];
            make_toast_top(localizestring(@"namelimit"));
        }
    }
}

 

使用变量lastinputstringrange记录最近一次输入的范围,超过指定范围截取字符串时,截取到该位置即可。