UITextView/UITextField 设置字数限制,字符截断问题解决
UITextView字数限制
- 添加代理,在代理方法里面限制字数,可以在
shouldChangeTextInRange
方法里面限制,或者在textViewDidChange
方法里面限制
- (void)viewDidLoad {
[super viewDidLoad];
// 添加并设置代理
UITextView *textView = [[UITextView alloc] init];
textView.frame = CGRectMake(0, 100, 390, 200);
textView.delegate = self;
[self.view addSubview:textView];
}
/// 方法一
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if (textView.text.length - range.length text.length > 10) {
NSLog(@"超出字数限制");
return NO;
}
return YES;
}
/// 方法二
- (void)textViewDidChange:(UITextView *)textView {
// 限制字数
if (textView.text.length > 10) {
textView.text = [textView.text substringToIndex:10];
}
}
UITextField字数限制
可以通过代理、Target
监听和通知对UITextField
字数进行限制
- 通过代理限制字数
// 添加代理
textField.delegate = self;
// 代理方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.text.length - range.length string.length > 20){
return NO;
}
return YES;
}
- 通过
Target
监听限制字数
// 添加监听
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
// 监听方法
- (void)textFieldDidChange:(UITextField *)textField {
if (textField.text.length > 20) {
textField.text = [textField.text substringToIndex:20];
}
}
- 通过通知限制字数
// NSNotificationCenter
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:) name:UITextFieldTextDidChangeNotification object:textField];
- (void)textFiledEditChanged:(NSNotification *)notification {
UITextField *textField = notification.object;
// 限制字数
if (textField.text.length > 10) {
textField.text = [textField.text substringToIndex:10];
}
}
高亮状态不做字数限制
- 在限制方法里面添加对高亮状态的识别,高亮状态时,不做字符长度限制,通用
UITextView/UITextField
// 高亮状态
if ([textView positionFromPosition:[textView markedTextRange].start offset:0]) {
return;
}
字符截断问题
- ❓通常一个
emoji
表情😓占用2个字符(部分占用3-4个),所以在使用字符阶段函数substringToIndex
的时候,一个emoji
表情会被截断,出现无法识别字符的情况,变成一个奇怪的字符 - 🔧解决方案:使用安全字符截断,附上
h文件和m文件
,可以创建一个NSString的Cut分类
使用,或者复制想要的函数,根据需要选择emojiSubstringToIndex
函数或者specialEmojiSubstringToIndex
函数,区别在注释里面
//
// NSString Cut.h
//
// Created by 猫南北学iOS on 2023/1/16.
//
// 字符截取分类
// 对英文占用字符数改为单个字母占用0.5个字符
//
// 字符长度规则:
// 1、中文占有1个字符
// 2、英文占用0.5个字符(⚠️区别于一般的字符长度计算)
// 3、emoji占用2个字符(部分emoji 3-4个字符)
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSString (Cut)
/// 根据序号字符截取
/// 规则:中文占有1个字符,英文占用0.5个字符,emoji占用2个字符
/// 修复emoji表情字符截断问题
- (NSString *)specialEmojiSubstringToIndex:(NSInteger)index;
/// 根据序号字符截取
/// 规则:中英文字符都视为1个字符,emoji占用2个字符
/// 修复emoji表情字符截断问题
- (NSString *)emojiSubstringToIndex:(NSInteger)index;
/// 获取剩余可输入字数
/// 规则:中文占有1个字符,英文占用0.5个字符,emoji占用2个字符
/// - Parameter length: 限制字数长度
- (NSString *)inputLengthWithLimitLength:(NSInteger)length;
/// 获取字符长度
/// 规则:中文占有1个字符,英文占用0.5个字符,emoji占用2个字符
/// 返回整数,自动向上取整
- (NSInteger)characterLength;
/// 获取字符长度
/// 规则:中文占有2个字符,英文占用1个字符,emoji占用4个字符
- (NSInteger)doubleCharacterLength;
@end
NS_ASSUME_NONNULL_END
//
// NSString Cut.m
//
// Created by 猫南北学iOS on 2023/1/16.
// 字符截取分类
//
#import "NSString Cut.h"
@implementation NSString (Cut)
/// 根据序号字符截取
/// 规则:中文占有1个字符,英文占用0.5个字符,emoji占用2个字符
/// 修复emoji表情字符截断问题
- (NSString *)specialEmojiSubstringToIndex:(NSInteger)index {
// 字符为空
if (!self || [self isEqualToString:@""]) {
return nil;
}
// 期望长度
NSInteger doubleIndex = index * 2;
// 循环截取
for (NSInteger i = 0; i < self.length; i ) {
// 截取
NSString *result = [self emojiSubstringToIndex:self.length - i];
// 截取的长度比较
if (result.doubleCharacterLength <= doubleIndex) {
return result;
}
}
// 出错
return nil;
}
/// 根据序号字符截取
/// 规则:中英文字符都视为1个字符,emoji占用2个字符
/// 修复emoji表情字符截断问题
- (NSString *)emojiSubstringToIndex:(NSInteger)index {
NSString *result = self;
if (result.length > index) {
NSRange range = [result rangeOfComposedCharacterSequenceAtIndex:index];
result = [result substringToIndex:(range.location)];
}
return result;
}
/// 获取剩余可输入字数
/// 规则:中文占有1个字符,英文占用0.5个字符,emoji占用2个字符
/// - Parameter length: 限制字数长度
- (NSString *)inputLengthWithLimitLength:(NSInteger)length {
if (length < self.characterLength) {
return @"0";
}
return [@(length - self.characterLength) stringValue];
}
/// 获取字符长度
/// 规则:中文占有1个字符,英文占用0.5个字符,emoji占用2个字符
/// 返回整数,自动向上取整
- (NSInteger)characterLength {
return ceil(self.doubleCharacterLength / 2.0);
}
/// 获取字符长度
/// 规则:中文占有2个字符,英文占用1个字符,emoji占用4个字符
- (NSInteger)doubleCharacterLength {
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData *data = [self dataUsingEncoding:encoding];
return [data length];
}
@end
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgcaibi
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01