博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
新浪微博客户端(58)-处理点击微博内容中的关键字
阅读量:6902 次
发布时间:2019-06-27

本文共 7285 字,大约阅读时间需要 24 分钟。

 

DJStatus.m

// 创建一个用于包含特殊文本的集合    NSMutableArray *specialTextArray = [NSMutableArray array];            // 取出数组中的文本块进行拼接    for (DJStatusPart *part in statusParts) {             NSAttributedString *subString = nil;        if (part.isSpecial) { // 判断是否是特殊文本(若是特殊文本,则进行特殊处理,超链接:变色,表情文本:更换成表情图片)            if (part.isEmotion) { //【Emotion表情】                                DJEmotion *emotion = [DJEmotionTool emotionWithChs:part.text];                if (emotion) { // 找到了当前文本对应的Emotion表情                    NSString *emotionName = emotion.png;                    NSString *imageName = nil;                                        if ([emotionName hasPrefix:@"d_"] || [emotionName hasPrefix:@"f_"] ||                        [emotionName hasPrefix:@"h_"] || [emotionName hasPrefix:@"l_"] || [emotionName hasPrefix:@"o_"] || [emotionName hasPrefix:@"w_"]) { // 默认表情                        imageName = [NSString stringWithFormat:@"EmotionIcons/default/%@",emotion.png];                    } else if ([emotionName hasPrefix:@"lxh_"]) { // 浪小花表情                        imageName = [NSString stringWithFormat:@"EmotionIcons/lxh/%@",emotion.png];                    }                                        NSTextAttachment *attachment = [[NSTextAttachment alloc] init];                    attachment.image = [UIImage imageNamed:imageName];                    attachment.bounds = CGRectMake(0, -4, 16, 16);                    subString = [NSAttributedString attributedStringWithAttachment:attachment];                } else {                    // 未在plist列表中找到对应表情,或该表情为Emoji                    subString = [[NSAttributedString alloc] initWithString:part.text];                }                            } else { // 【超链接&昵称】将字体颜色修改为DJColor(82,118,169)                subString = [[NSAttributedString alloc] initWithString:part.text attributes:@{NSForegroundColorAttributeName : DJColor(82, 118, 169)}];                                // 保存非表情的特殊文字                NSUInteger location = attributedText.length;                NSUInteger length = part.text.length;                DJSpecialText *specialText = [[DJSpecialText alloc] init];                specialText.text = part.text;                specialText.range = NSMakeRange(location, length);                [specialTextArray addObject:specialText];                            }        } else { // 【普通文本】不做任何处理            subString = [[NSAttributedString alloc] initWithString:part.text];        }        [attributedText appendAttributedString:subString];    }            // 将保存有特殊文本的集合添加到DJStatus的属性上    [attributedText addAttribute:@"special" value:specialTextArray range:NSMakeRange(0, 1)];

 

DJSpecialText.h

#import 
@interface DJSpecialText : NSObject/** 特殊文本的内容 */@property (nonatomic,copy) NSString *text;/** 特殊文本的范围 */@property (nonatomic,assign) NSRange range;/** 特殊文本的矩形框 NSArray中存放的是CGRect对象 */@property (nonatomic,strong) NSArray *rects;@end

DJStatusTextView.m

#import "DJStatusTextView.h"#import "DJSpecialText.h"#define DJStatusTextViewCoverTag 999@implementation DJStatusTextView- (instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {                self.backgroundColor = [UIColor clearColor];        self.editable = NO; // 禁止编辑        self.textContainerInset = UIEdgeInsetsMake(0, -5, 0, -5);        self.scrollEnabled = NO; // 禁止滚动            }    return self;}// 类似于android里的 MotionEvent.ACTION_DOWN- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; // 获取触摸点的坐标 CGPoint touchPoint = [touch locationInView:self]; // 计算特殊文本所在的矩形框 [self setupAttributedTextRects]; // 根据触摸点判断是否在点击的是特殊文本 DJSpecialText *specialText = [self specialTextWithTouchPoint:touchPoint]; // 如果是特殊文本,则为其添加一个浅色背景 if (specialText) { NSArray *rectArray = specialText.rects; for (NSValue *rectValue in rectArray) { CGRect rect = rectValue.CGRectValue; // 取出当前文本所在的CGRect // 添加浅色背景 UIView *cover = [[UIView alloc] init]; cover.backgroundColor = DJColor(179, 193, 211); cover.frame = rect; cover.tag = DJStatusTextViewCoverTag; cover.layer.cornerRadius = 3; [self insertSubview:cover atIndex:0]; } } DJLog(@"点击了TextView......."); }/** 计算特殊文本所在的CGRect,并将其作为特殊文本的属性 */- (void)setupAttributedTextRects { NSArray *specialTextArray = [self.attributedText attribute:@"special" atIndex:0 effectiveRange:NULL]; for (DJSpecialText *specialText in specialTextArray) { // 设置当前TextView选中范围 self.selectedRange = specialText.range; // 获取选中文字的CGRect NSArray *selectionRects = [self selectionRectsForRange:self.selectedTextRange]; // 清空当前TextView选中范围 self.selectedRange = NSMakeRange(0, 0); NSMutableArray *attributeTextRects = [NSMutableArray array]; // 属性文本所在的CGRect数组 for (UITextSelectionRect *selectionRect in selectionRects) { // 取出当前特殊文本所在的CGRect CGRect rect = selectionRect.rect; // 若存在垃圾矩形框,则跳过 if (rect.size.width == 0 || rect.size.height == 0) continue; // 添加当前CGRect到其所在的CGRect数组(由于CGRect是结构体,无法直接添加到NSArray当中,故需要将其转换为NSValue对象,再添加到数组) [attributeTextRects addObject:[NSValue valueWithCGRect:rect]]; } // 将特殊文本所在CGRect集合设置进去 specialText.rects = attributeTextRects; } }/** 传入一个触摸点,返回当前触摸点所在的特殊文本,若没有,则返回空 */- (DJSpecialText *)specialTextWithTouchPoint:(CGPoint)touchPoint {
NSArray *specialTextArray = [self.attributedText attribute:@"special" atIndex:0 effectiveRange:NULL]; for (DJSpecialText *specialText in specialTextArray) { // 取出特殊文本所在的CGRect范围 NSArray *rectArray = specialText.rects; // 遍历当前特殊文本所在的矩形框 for (NSValue *rectValue in rectArray) { if (CGRectContainsPoint(rectValue.CGRectValue, touchPoint)) { return specialText; // 若当前矩形框包含触摸点,则将该特殊文本返回 } } } return nil;}// 类似于android里的 MotionEvent.ACTION_UP- (void)touchesEnded:(NSSet
*)touches withEvent:(UIEvent *)event { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self touchesCancelled:touches withEvent:event]; });}// 当触摸事件被打断时调用此方法- (void)touchesCancelled:(NSSet
*)touches withEvent:(UIEvent *)event { // 去掉特殊字符后面的高亮背景 for (UIView *child in self.subviews) { if (child.tag == DJStatusTextViewCoverTag) [child removeFromSuperview]; }}// iOS触摸事件传递// 1.判断点在谁身上,调用pointInside,返回YES的控件就是触摸点所在的控件// 2.由触摸点所在的UI控件选出处理事件的UI控件,调用hitTest:(CGPoint)point withEvent// 此方法是用来决定触摸事件是由该控件上的哪一个子控件来处理//- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {//////}// 这个方法类似于android里面的onTouchEvent,需要返回一个布尔值,该布尔值代表是否由该控件消费掉此触摸事件- (BOOL)pointInside:(CGPoint)touchPoint withEvent:(UIEvent *)event {
[self setupAttributedTextRects]; DJSpecialText *specialText = [self specialTextWithTouchPoint:touchPoint]; if (specialText) { // 判断当前触摸点是否在特殊文本之上,若在,则认为是点击了特殊文本;若不在,则认为是点击了tableView上的Cell. return YES; } else { return NO; }}@end

 

 

最终效果:

转载地址:http://xlpdl.baihongyu.com/

你可能感兴趣的文章
hbase源码系列(十五)终结篇&Scan续集-->如何查询出来下一个KeyValue
查看>>
Linux学习总结(4)——Centos6.5使用yum安装mysql——快速上手必备
查看>>
Spring Boot学习总结(1)——Spring Boot入门
查看>>
C/C++ 宏带来的奇技淫巧 转载
查看>>
CocoaPods requires your terminal to be using UTF-8 encoding
查看>>
CSS3 圆角(border-radius)
查看>>
最大子数组
查看>>
用telnet命令,POP3接收邮件
查看>>
Nginx 关于 location 的匹配规则详解
查看>>
OutputStream、InputStream 、FileOutputStream、FileInputStream,字节流API
查看>>
10. Python面向对象
查看>>
python3与 python2 urllib模块区别
查看>>
关于props 和state
查看>>
跟我学算法-tensorflow 实现线性拟合
查看>>
redis使用管道pipeline提升批量操作性能(php演示)
查看>>
python: file_handling 解决工作中出现的文件处理需求
查看>>
HTML5 拖放(Drag 和 Drop)功能开发——浅谈dataTransfer对象
查看>>
灰度图像亮度对比度调整的简单代码
查看>>
shell测试题上机实验
查看>>
[转]二维数组和二级指针的传递问题
查看>>