日常开发中,我们经常使用UITextView,然而系统自身的UITextView并不支持占位字符的设置,限制最大输入字符数的时候,又需要去实现协议,在协议中去做操作
-
一般我们的做法:新建一个继承UITextView的类,然后在这个类里面进行监听输入事件等,来判断占位字符,最大输入数,使用的时候,导入新建的类头文件.这么做的话,1、项目交接额外增加沟通事件,2、规范,3、使用繁琐,4、不够高大上😂
-
最近学习了runtime,当然要使用runtime来做一套了😂,下面进入正题
runtime实现UITextView占位字符
- 新建UITextView的扩展类
- 扩展类添加placeHolder对象,并实现set,get方法
(void)setPlaceHolder:(NSString *)placeHolder {
objc_setAssociatedObject(self, @"placeHolderKey", placeHolder, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)placeHolder {
return objc_getAssociatedObject(self, @"placeHolderKey");
}
- (UILabel *)placeHolderLabel {
UILabel *placeHolderLabel = objc_getAssociatedObject(self, @"placeHolderLabel");
if (!placeHolderLabel) {
placeHolderLabel = [UILabel new];
objc_setAssociatedObject(self, @"placeHolderLabel", placeHolderLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self insertSubview:placeHolderLabel atIndex:0];
UIEdgeInsets textContainerInset = self.textContainerInset;
CGFloat lineFragmentPadding = self.textContainer.lineFragmentPadding;
CGFloat x = lineFragmentPadding + textContainerInset.left + self.layer.borderWidth; //uitextview的左间距
CGFloat y = textContainerInset.top + self.layer.borderWidth; // 上间距
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self];
[placeHolderLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(x);
make.top.mas_equalTo(y);
make.width.mas_equalTo(self);
make.height.mas_greaterThanOrEqualTo(0);
}];
}
}
- (void)textDidChange {
if (self.placeHolder) {
if (self.text.length) {
self.placeHolderLabel.hidden = YES;
}else {
self.placeHolderLabel.hidden = NO;
self.placeHolderLabel.font = self.font?self.font:self.cacutDefaultFont;
self.placeHolderLabel.textAlignment = self.textAlignment;
self.placeHolderLabel.text = self.placeHolder;
}
}else {
self.placeHolderLabel.hidden = YES;
}
}
- 新建一个方法,于系统的setText方法交换,方法里面调用textDidChange来判断是否显示占位字符
+ (void)load {
[super load];
method_exchangeImplementations(class_getInstanceMethod(self, @selector(setText:)), class_getInstanceMethod(self, @selector(wsl_setText:)));
}
- (void)wsl_setText: (NSString *)text {
[self wsl_setText:text];
[self textDidChange];
}
- 因为我们使用的通知,所以要进行释放,新建delloc的方法与系统交换
+ (void)load {
[super load];
method_exchangeImplementations(class_getInstanceMethod(self, @selector(delegate)), class_getInstanceMethod(self, @selector(wsl_delloc)));
method_exchangeImplementations(class_getInstanceMethod(self, @selector(setText:)), class_getInstanceMethod(self, @selector(wsl_setText:)));
}
- (void)wsl_delloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self wsl_delloc];
}
runtime实现最大字符数限制
- 创建maxNum最大输入数对象,实现set,get方法
- (void)setMaxNum:(NSInteger)maxNum {
objc_setAssociatedObject(self, @"maxNum", @(maxNum), OBJC_ASSOCIATION_ASSIGN);
//这里我们在set方法中创建了通知来监听text的改变
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self];
}
- (NSInteger)maxNum {
return [objc_getAssociatedObject(self, @"maxNum") integerValue];
}
- 在textDidChange方法中实现字符长度的限制,这里我做了中文字符的处理
NSString *nsTextContent = self.text;
NSInteger existTextNum = nsTextContent.length;
if (self.maxNum && existTextNum > self.maxNum) {
//截取到最大位置的字符
NSString *lang = [[UIApplication sharedApplication]textInputMode].primaryLanguage;
if ([lang isEqualToString:@"zh-Hans"]) { //中文输入
UITextRange *selectedRange = [self markedTextRange];
//获取高亮部分
UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
if (!position) {// 没有高亮选择的字,则对已输入的文字进行字数统计和限制
if (nsTextContent.length > self.maxNum) {
self.text = [nsTextContent substringToIndex:self.maxNum];
}
}
else{//有高亮选择的字符串,则暂不对文字进行统计和限制
}
}else{//中文输入法以外的直接对其统计限制即可,不考虑其他语种情况
if (nsTextContent.length > self.maxNum) {
self.text = [nsTextContent substringToIndex:self.maxNum];
}
}
}
网友评论