Static const int max_limit_nums = +; /**< Input number limit * /
// Self.inputnumbertipslabel a label on the view of the controller to show the input quantity hint
#pragmamark-uitextviewdelegate-(BOOL) TextView: (Uitextview *) TextView Shouldchangetextinrange: (nsrange) Range Replacementtext: (NSString*) text{Uitextrange*selectedrange1 =[TextView Markedtextrange]; //get highlighted partsUitextposition *pos = [TextView positionFromPosition:selectedRange1.start offset:0]; //get highlighted parts of the content//NSString * SelectedText = [TextView textinrange:selectedrange]; //allow input If there is a highlight and the current word start position is less than the maximum limit if(SelectedRange1 &&POS) {Nsinteger Startoffset=[TextView offsetFromPosition:textView.beginningOfDocument ToPosition:selectedRange1.start]; Nsinteger Endoffset=[TextView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange1.end]; Nsrange Offsetrange= Nsmakerange (Startoffset, Endoffset-startoffset); if(Offsetrange.location <max_limit_nums) { returnYES; } Else { returnNO; }} nsstring*comcatstr =[Textview.text Stringbyreplacingcharactersinrange:range Withstring:text]; //Nsinteger caninputlen = max_limit_nums-comcatstr.length;Nsinteger Caninputlen = max_limit_nums-[Comcatstr Getstringlengthifisemojilengthasone]; if(Caninputlen >=0) { returnYES; } Else { //Nsinteger len = text.length + Caninputlen;Nsinteger len = [text Getstringlengthifisemojilengthasone] +Caninputlen; //prevents error when Text.length + Caninputlen < 0 o'clock, making rg.length an illegal maximum positive numberNsrange RG = {0, MAX (Len,0)}; if(Rg.length >0) {NSString*s =@""; //determine if only normal characters or ASC codes (for Chinese and Emoticons return no)BOOL ASC =[text canbeconvertedtoencoding:nsasciistringencoding]; if(ASC) {s= [text Substringwithrange:rg];//because it's ASCII, it's not wrong to take it directly. } Else{__block Nsinteger idx=0; __block NSString*trimstring =@"";//the truncated string//using string traversal, this method can know exactly whether each emoji is a Unicode or two[Text Enumeratesubstringsinrange:nsmakerange (0, [text length]) options:nsstringenumerationbycomposedcharactersequences Usingblock:^ (nsstring* substring, nsrange substringrange, Nsrange Enclosingrange, bool*stop) { //Nsinteger steplen = substring.length;Nsinteger Steplen =[substring getstringlengthifisemojilengthasone]; if(IDX >=rg.length) {*stop = YES;//remove the need to break, improve efficiency return ; } trimstring=[trimstring stringbyappendingstring:substring]; IDX= idx +Steplen; }]; S=trimstring; } __block BOOL hasattachment=NO; [Textview.attributedtext Enumerateattributesinrange:nsmakerange (0, textView.attributedText.length) options:nsattributedstringenumerationreverse usingblock:^ (Nsdictionary *attrs, Nsrange Range, BOOL *stop) { if(attrs[@"nsattachment"]) { *stop =YES; Hasattachment=YES; } }]; if(TextView.text.length >max_limit_nums) {ktoastwithstring (@"input reached limit") if(hasattachment) {[Textview.attributedtext Attributedsubstringfromrange:nsmake Range (0, Max_limit_nums)]; } Else { //rang refers to the substitution process from the current cursor (note that if yes is returned after this sentence is executed, the Didchange event is triggered)[TextView settext:[textview.text stringbyreplacingcharactersinrange:range withstring:s]; } } //since it is out of the partial interception, which must be the maximum limit. Self.inputNumberTipsLabel.text = [NSString stringWithFormat:@"%d/%ld",0,(Long) Max_limit_nums]; } if(TextView.text.length >=max_limit_nums) {ktoastwithstring (@"input reached limit") } returnNO; } }- (void) Textviewdidchange: (Uitextview *) textview{//placeholder text display or not_submitevaluationbtn.enabled =Self.evaluationTextView.hasText; Uitextrange*selectedrange1 =[TextView Markedtextrange]; //get highlighted partsUitextposition *pos = [TextView positionFromPosition:selectedRange1.start offset:0]; //If the highlight is changing in the change, don't count the characters. if(SelectedRange1 &&POS) { return; } nsstring*nstextcontent =Textview.text; //Nsinteger existtextnum = nstextcontent.length;Nsinteger Existtextnum =[Nstextcontent Getstringlengthifisemojilengthasone]; if(Existtextnum >max_limit_nums) {ktoastwithstring (@"input reached limit") __block BOOL hasattachment=NO; [Textview.attributedtext Enumerateattributesinrange:nsmakerange (0, textView.attributedText.length) options:nsattributedstringenumerationreverse usingblock:^ (Nsdictionary *attrs, Nsrange Range, BOOL *stop) { if(attrs[@"nsattachment"]) { *stop =YES; Hasattachment=YES; } }]; if(hasattachment) {Textview.attributedtext= [Textview.attributedtext Attributedsubstringfromrange:nsmakerange (0, Max_limit_nums +[Textview.text Emojicount]); } Else { //The character that is intercepted to the maximum position (because the outside section is processed at should, which is where the efficiency is no longer judged)NSString *s = [nstextcontent substringtoindex: (Max_limit_nums +[Textview.text Emojicount]); [TextView settext:s]; } } //do not let display negative mouth daySelf.inputNumberTipsLabel.text = [NSString stringWithFormat:@"%tu/%tu", MAX (0, Max_limit_nums-existtextnum), max_limit_nums];}
TextView text length, custom expression length is 1,emoj expression length is 1, input limit