大致思路
- 创建MXPointAtManager类把@功能封装在一起,新增功能模块与原代码尽量解耦。
- 输入@符号,弹出群成员列表,选择成员
- 删除@成员,输入框要同时把成员跟@符号一起删除
- 监听方法如下,该代理方法有range可以定位,replacementText可以判断是插入、删除。
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
-
MXPointAtManager对外的API
///当前是否有@信息
@property (nonatomic, assign, readonly) BOOL havedAt;
///返回当前@信息里的userId
@property (nonatomic, strong, readonly) NSArray *userIdsArr;
///插入@
- (void)pointAtFriend:(MXInputTextView *)textView inRange:(NSRange)range;
///删除@
- (BOOL)delPointAt:(MXInputTextView *)textView withRange:(NSRange)range ;
///清空@信息
- (void)clearAtMessage;
MXInputTextView 继承 YYTextView类
-
输入@符号
if ([@"@" isEqualToString:text]) {
///群聊才有@功能
[[MXPointAtManager sharedManager] pointAtFriend:self.chatToolBar.inputTextView inRange:range];
}
判断是否进入选择@的人页面
- (void)pointAtFriend:(MXInputTextView *)textView inRange:(NSRange)range {
[textView resignFirstResponder];
//选择完后回调
void (^selectBlock)(NSArray *) = ^(NSArray *friendsArr) {
///name: 名称 userID: 对应用户ID
[self addPointAt:textView inRange:range withName:name andUserID:obj.userid];
};
NSArray *tempArr = 排序后的群成员列表(移除自己);
NSDictionary *param = @{@"dataSourceArr":tempArr,
@"selectedBlock":selectBlock};
///跳转选择列表
MXRoute(@"ChooseContactAtVC", param);
}
选择@的群友后的处理,拼接[@群友名称],保存[@群友名称]的NSRange,以便之后删除操作。
把textView.text根据range 分隔成两块frontText、behindText,在frontText拼上当前@信息,再重新拼接赋值给textView 设置光标位置
- (void)addPointAt:(MXInputTextView *)textView inRange:(NSRange)range withName:(NSString *)nickname andUserID:(NSString *)userID{
NSString *text = textView.text;
NSString *frontText = [text substringToIndex:range.location+1];
NSString *behindText = @"";
if (text.length >= range.location + 1) {
behindText = [text substringFromIndex:range.location + 1];
}
frontText = StrF(@"%@%@ ", frontText, nickname);
if ([StringUtil isEmpty:nickname]) {
frontText = StrF(@"%@%@", frontText, nickname);
}
NSString *atName = StrF(@"%@%@ ", @"@", nickname);
if ([StringUtil isEmpty:nickname]) {
atName = StrF(@"%@%@", @"@", nickname);
}
NSRange inRange = [frontText rangeOfString:atName options:NSBackwardsSearch];
if (inRange.location == NSNotFound) {
return;
}
textView.text = StrF(@"%@%@", frontText, behindText);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//改变光标的位置
NSRange range = NSMakeRange(inRange.location + inRange.length, 0);
textView.selectedRange = range;
[textView becomeFirstResponder];
});
if ([StringUtil isEmpty:userID]) {
return;
}
//pointAtDataMDic pointAtRangeMDic 保存着同一个key
[self.pointAtDataMDic setValue:nickname?:@"" forKey:userID];
[self.pointAtRangeMDic setValue:userID forKey:NSStringFromRange(inRange)];
}
-
删除@成员
把textView.text根据range 分隔成两块frontText、behindText,在frontText查找@相关信息,查找到后删除,再重新拼接赋值给textView,设置光标位置
- (BOOL)delPointAt:(MXInputTextView *)textView withRange:(NSRange)range {
if (textView.text.length < (range.location + 1)) {
return YES;
}
NSString *subText = [textView.text substringToIndex:range.location + 1];
//删除的字符是否是 ' '
if (!([subText characterAtIndex:subText.length-1] == ' ')) {
return YES;
}
NSInteger index = -1;
for(NSInteger i = subText.length - 1; i >= 0; i--){
if ([subText characterAtIndex:i] == '@' ) {
index = i;
break;
}
}
if (index == -1) {
return YES;
}
NSRange rang = NSMakeRange(index, subText.length - index);
NSString *rangeString = NSStringFromRange(rang);
if (![self.pointAtRangeMDic.allKeys containsObject:rangeString]) {
return YES;
}
NSString *userID = self.pointAtRangeMDic[rangeString];
[self.pointAtDataMDic removeObjectForKey:userID];
[self.pointAtRangeMDic removeObjectForKey:rangeString];
//从光标处分隔
NSString *text = textView.text;
NSString *frontText = [text substringToIndex:range.location+1];
NSString *behindText = @"";
if (text.length >= range.location + 1) {
behindText = [text substringFromIndex:range.location + 1];
}
frontText = [frontText substringToIndex:rang.location];
NSRange inRange = [textView.text rangeOfString:frontText options:NSBackwardsSearch];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//改变光标的位置
textView.text = StrF(@"%@%@", frontText, behindText);
NSRange range = NSMakeRange(inRange.location + inRange.length, 0);
textView.selectedRange = range;
[textView becomeFirstResponder];
});
return NO;
}
-
输入框发送的时候判断当前是否有@信息,有的话就组装到Message信息中去
if ([MXPointAtManager sharedManager].havedAt) {
///组装相关Message
}
///发送完记得清楚本次@信息
[[MXPointAtManager sharedManager] clearAtMessage];
-
会话列表数据库,增加isAt字段,存储是否有@自己的信息。接受到信息后把@自己的信息持久化到本地。根据这个字段显示类似微信[有人@我]的提示信息
网友评论