目的
仿用于仿微博、微信、釘釘的艾特(@)功能【話題功能類型處理】【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中,如何對特殊文本進行整體綁定