iOS @功能的部分实现思路

时间:2022-05-16 06:08:54

需求描述

1. 发布信息时,通过键盘键入@符号,或者点选相关功能键,唤醒@列表,进行选择

2.选择结束后,输入栏改色显示相关内容

3.删除时,整体删除@区块,且不能让光标落在@区块之间

 

实现步骤

1. 键入@符号,触发相关功能

 1 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
 2     //判断键入的字符
 3     if ([text isEqualToString:@"@"]) {
 4         //触发相关功能
 5         //[self pickRemaidBtnClick];
 6         return NO;
 7     }
 8 
 9     return YES;
10 }

 

2. @区块颜色修改

(1)使用到的正则表达式

#define kATRegular @"@[\u4e00-\u9fa5\w\-\_]  "

(2)获取匹配到的区块下标数组

  (NSArray *) getMatchsWithStr : (NSString *) text {
    // 找到文本中所有的@
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:kATRegular options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *matches = [regex matchesInString:text options:NSMatchingReportProgress range:NSMakeRange(0, [text length])];
    return matches;
}

(3)修改文本颜色

-(void)textViewDidChange:(UITextView *)textView {
    NSArray *matchs = [RemaidUserUtils getMatchsWithStr:textView.text];
    //改色
    [textView.textStorage addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithHexString:@"#333333"] range:NSMakeRange(0, textView.text.length)];
    for (NSTextCheckingResult *match in matchs)
    {
        [textView.textStorage addAttribute:NSForegroundColorAttributeName value:BLUECOLOR range:NSMakeRange(match.range.location, match.range.length - 1)];
    }
}

 

3.删除时整体删除@区块

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{

    if ([text isEqualToString:@""])
    {
        NSRange selectRange = textView.selectedRange;
        if (selectRange.length > 0)
        {
            //用户长按选择文本时不处理
            return YES;
        }
        
        // 判断删除的是一个@中间的字符就整体删除
        NSMutableString *string = [NSMutableString stringWithString:textView.text];
        NSArray *matches = [RemaidUserUtils getMatchsWithStr:string];
        
        BOOL inAt = NO;
        NSInteger index = range.location;
        for (NSTextCheckingResult *match in matches)
        {
            NSRange newRange = NSMakeRange(match.range.location   1, match.range.length - 1);
            if (NSLocationInRange(range.location, newRange))
            {
                inAt = YES;
                index = match.range.location;
                [textView.textStorage replaceCharactersInRange:match.range withString:@""];
                textView.selectedRange = NSMakeRange(index, 0);
                [self textViewDidChange:textView];
                return NO;
                break;
            }
        }
    }
    
    return YES;
}

 

4.不允许光标落在@区块之间

- (void)textViewDidChangeSelection:(UITextView *)textView {
    // 光标不能点落在@词中间
    NSRange range = textView.selectedRange;
    if (range.length > 0)
    {
        // 选择文本时可以
        return;
    }
    
    NSArray *matches = [RemaidUserUtils getMatchsWithStr:textView.text];
    
    for (NSTextCheckingResult *match in matches)
    {
        NSRange newRange = NSMakeRange(match.range.location   1, match.range.length - 1);
        if (NSLocationInRange(range.location, newRange))
        {
            if (range.location == match.range.location   1) {
                textView.selectedRange = NSMakeRange(match.range.location   match.range.length, 0);
            } else {
                textView.selectedRange = NSMakeRange(match.range.location , 0);
            }
            break;
        }
    }
}

 

BY: chu