iOS 艾特、話題功能實現,支持OC、Swift

目的

仿用于仿微博、微信、釘釘的艾特(@)功能【話題功能類型處理】【swift 已經支持】

  • 艾特所在的特殊文本不支持編輯,為一個整體存在

一、實現功能

  • 支持OC和Swift
  • 以UITextView為基礎實現,可以輸入時支持特殊文本變色
  • 支持 特殊文本列表輸出(包含在文本中的定位信息、可以自定義其它內容),減少服務器的交互
  • 富文本用 YYLabel顯示,支持可點擊
  • 輸入時,不支持艾特點擊

二、效果圖

2021-04-30.png

三、如何使用

與UITextView使用一樣,只是方法的拓展【Swift 同理調用】

1、導入頭文件

#import "ATTextView.h"

2、使用時,集成ATTextView即可

3、插入話題或人名等特殊文本時,需要更新光標位置

    NSArray *results = self.textView.atUserList;

    NSLog(@"輸出打印:");
    for (TextViewBinding *model in results) {
        NSLog(@"user info - name:%@ - location:%ld",model.name, model.range.location);
    }

4、獲取已經拆入的話題或人名等特殊文本列表

- (void)updateUIWithUser:(User *)user {
        
    NSString *insertText = [NSString stringWithFormat:@"@%@ ", user.name];
    TextViewBinding *bindingModel = [[TextViewBinding alloc]initWithName:user.name
                                                                  userId:user.userId];

    // 插入前手動判斷
//    if (self.textView.text.length+insertText.length > 20) {
//        NSLog(@"已經超出最大輸入限制了....");
//        return;
//    }
    
    [self.textView insertText:insertText];
    NSMutableAttributedString *tmpAString = [[NSMutableAttributedString alloc] initWithAttributedString:self.textView.attributedText];
    NSRange range = NSMakeRange(self.textView.selectedRange.location - insertText.length, insertText.length);
    [tmpAString setAttributes:@{NSForegroundColorAttributeName:k_hightColor,
                                NSFontAttributeName:k_defaultFont,
                                TextBindingAttributeName:bindingModel}
                        range:range];

    // 解決光標在插入‘特殊文本’后 移動到文本最后的問題
    NSInteger lastCursorLocation = self.textView.cursorLocation;
    self.textView.attributedText = tmpAString;
    self.textView.selectedRange = NSMakeRange(lastCursorLocation, self.textView.selectedRange.length);
    self.textView.cursorLocation = lastCursorLocation;
}

四、說重點?。?!

1、通過實現UITextViewDelegate中的三個方法完成主要的核心操作

用于處理光標移動的邏輯

- (void)textViewDidChangeSelection:(UITextView *)textView

文本有改變時,重置attributedText屬性

- (void)textViewDidChange:(UITextView *)textView

文本進行增、刪、改時的處理邏輯

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

2、通過正則表達時,查找定位@符號列表數據

#define kATRegular      @"@[\\u4e00-\\u9fa5\\w\\-\\_]+ "
- (NSArray<TextViewBinding *> *)getResultsListArrayWithTextView:(NSAttributedString *)attributedString {
    __block NSMutableArray *resultArray = [NSMutableArray array];
    NSRegularExpression *iExpression = [NSRegularExpression regularExpressionWithPattern:kATRegular options:0 error:NULL];
    [iExpression enumerateMatchesInString:attributedString.string
                                  options:0
                                    range:NSMakeRange(0, attributedString.string.length)
                               usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
        NSRange resultRange = result.range;
        NSString *atString = [self.text substringWithRange:result.range];
        TextViewBinding *bindingModel = [attributedString attribute:TextBindingAttributeName atIndex:resultRange.location longestEffectiveRange:&resultRange inRange:NSMakeRange(0, atString.length)];
        if (bindingModel) {
            bindingModel.range = result.range;
            [resultArray addObject:bindingModel];
        }
    }];
    return resultArray;
}

五、文檔參考

為了研究這個 艾特 功能花費了大量的時間和精力,也參考了網上許多的案例實現。
以下為主要參考文檔鏈接,需要請查看:
1、iOS中@功能的完整實現
2、UITextView中,如何對特殊文本進行整體綁定

更多問題請issue me?。?!GitHub倉庫地址

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容