1.微信@功能实现思路
最近在封装IM聊天功能,微信@功能思考了许久想出了一个办法,用富文本的方式将@内容的空格特殊化,自定义两个NSAttributedStringKey,分别记录名称和id。
2.核心代码
NSAttributedStringKey const NSNickNameAttributeName = @"NSNickNameAttributeName";
NSAttributedStringKey const NSUserIDAttributeName = @"NSUserIDAttributeName";
///textView输入内容处理
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text isEqualToString:@""]) {
NSRange selectRange = textView.selectedRange;
if (selectRange.length > 0 || textView.text.length == 0) {
//长按或者没有内容
return YES;
}
//判断是否需要删除@内容
NSInteger index = range.location;
NSMutableAttributedString *textAtt = [[NSMutableAttributedString alloc] initWithAttributedString:textView.attributedText];
NSAttributedString *subAtt = [textView.attributedText attributedSubstringFromRange:NSMakeRange(0, index+1)];
if ([subAtt.string containsString:@"@"] && [subAtt attribute:NSNickNameAttributeName atIndex:index effectiveRange:nil]) {
NSInteger ans = 0;
for (NSUInteger i = subAtt.length - 1; i>=0; i--) {
NSString *tmp = [subAtt.string substringWithRange:NSMakeRange(i, 1)];
if ([tmp isEqualToString:@"@"]) {
ans = i;
break;
}
}
[textAtt replaceCharactersInRange:NSMakeRange(ans, index - ans + 1) withString:@""];
textView.attributedText = textAtt;
return NO;
}
return YES;
}
if ((textView.text.length + text.length) >=250) {
//字数限制
return NO;
}
if ([text isEqualToString:@"@"]) {
!self.callSomeone?:self.callSomeone();
return YES;
}
if ([text isEqualToString:@"\n"]){
NSMutableArray *atArr = [self checkIfNeedAtSomeoneWithTextView:textView];
if ([_delegate respondsToSelector:@selector(inputToolbar:sendContent:andAtArr:)]) {
[_delegate inputToolbar:self sendContent:self.textInput.attributedText andAtArr:atArr];
}
self.textInput.attributedText = nil;
[self.textInput.delegate textViewDidChange:self.textInput];
return NO;
}else
return YES;
}
///添加@信息
- (void)changeTextViewWithName:(NSString *)nickname andUserID:(NSString *)userID{
NSMutableAttributedString *aStr = [[NSMutableAttributedString alloc] initWithAttributedString:self.textInput.attributedText];
NSMutableAttributedString *bStr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ ", nickname]];
[bStr setAttributes:@{NSNickNameAttributeName : nickname, NSUserIDAttributeName:userID} range:NSMakeRange(bStr.length - 1, 1)];
[aStr appendAttributedString:bStr];
[aStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:17] range:NSMakeRange(0, aStr.length)];
self.textInput.attributedText = aStr;
}
///查找@内容
-(NSMutableArray *)checkIfNeedAtSomeoneWithTextView:(UITextView *)textView{
NSMutableArray *atArr = NSMutableArray.array;
[textView.attributedText enumerateAttributesInRange:NSMakeRange(0, textView.attributedText.length) options:1 usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
if (attrs[NSUserIDAttributeName]) {
NSString *userID = attrs[NSUserIDAttributeName];
NSString *nickName = attrs[NSNickNameAttributeName];
if (range.location > nickName.length) {
NSString *tNickName = [textView.text substringWithRange:NSMakeRange(range.location - nickName.length, nickName.length)];
NSString *atStr = [textView.text substringWithRange:NSMakeRange(range.location - nickName.length - 1, 1)];
if ([tNickName isEqualToString:nickName] && [atStr isEqualToString:@"@"]) {
[atArr addObject:userID];
}
}
}
}];
return atArr;
}
3.总结
网上找了挺多实现方式的,包括图片化@内容、正则判断、记录@内容的位置和信息等,这些方式都不完善且有一定的漏洞,最后只能自己想办法实现了。在这里记录一下,有时间再弄个demo
网友评论