美文网首页微信相关
iOS 仿微信@功能

iOS 仿微信@功能

作者: daobao777 | 来源:发表于2020-06-06 09:49 被阅读0次

    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

    相关文章

      网友评论

        本文标题:iOS 仿微信@功能

        本文链接:https://www.haomeiwen.com/subject/teurvhtx.html