iOS富文本Label实现点击事件,类似Word在横线上输入编辑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS富文本Label实现点击事件,类似Word在横线上输入编辑相关的知识,希望对你有一定的参考价值。

参考技术A .h

NS_ASSUME_NONNULL_BEGIN

@interface GHAttributesLabel : UILabel
typedef void(^GHAttributesBlock)(NSRange poinRange);
/**

@param text 传入富文本类型的字符串
@param actionText 要响应事件的字符串
*/

/**
点击事件回调
*/
@property (nonatomic , copy) GHAttributesBlock actionBlock;

.m
//
// GHAttributesLabel.m
// GHAttributesLabelDemo
//
// Created by zhaozhiwei on 2019/1/20.
// Copyright © 2019年 GHome. All rights reserved.
//

@interface GHTextView : UITextView

@end
@implementation GHTextView

@end

@interface GHAttributesLabel()<UITextViewDelegate>

@property (nonatomic , strong) GHTextView *textView ;

@property (nonatomic , copy) NSString *actionText ;

/** <#注释#>*/
@property (nonatomic, assign) NSRange range;

@end
@implementation GHAttributesLabel

// return YES;


@end

使用
-(void)test
GHAttributesLabel *attributesLabel = [[GHAttributesLabel alloc]initWithFrame:CGRectMake(10, 200, [UIScreen mainScreen].bounds.size.width - 20, 250)];

// NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:temp];

// NSRange range = [temp rangeOfString:actionStr];
// NSLog(@"range%@",NSStringFromRange(range));
NSArray *actionArr = [self rangeOfSubString:actionStr inString:temp];
NSLog(@"===:%@",[self rangeOfSubString:actionStr inString:temp]);
for (int i = 0; i < actionArr.count; i++)
NSValue *value = actionArr[i];
NSRange actionRange = [value rangeValue];
[attrStr addAttribute:NSLinkAttributeName
value:actionStr
range: actionRange];





return rangeArray;


-(NSMutableAttributedString *)keyWords:(NSString *)keyWords withKeyWordsColor:(UIColor *)color


iOS富文本实现(-):私密阅读效果

参考技术A

废话不多说,咱们直接先看效果!看是不是咱想要的哈

就像上图所示的示例:
1.项目需求
项目中要实现私密阅读信息的功能,即一次只能查看一行文字功能。当我们手指点击或者滑动到某一行文字的时候,该行文字会显示出来,而当我们手指离开该行的时候,文字会隐藏起来。
主要目的是, 该App要防止用户截屏,真正做到隐私无泄漏。
2.大致思考说明
明白了我们的核心需求后,那么对这个问题的思考点落脚:
首先要实现文本的行数的监听控制,那么自然要用到label中的 富文本展示功能;
其次是覆盖到的文本位置区域要尽可能的准确无误;
最后当然是手指滑动以及点击过程中的监听交互与覆盖层的处理逻辑。
针对以上问题,要怎么来解决呢?

总的来说,基本从实现该功能来说,其实可以简单总结为三步曲
1.富文本文字的设置
这块主要涉及对文字大小,字与字的间距,行间距,甚至未来的段间距等相关的设置,这是富文本研究的基础工作。

2.遮盖层的选择研究
关于遮盖层方面,其实一般开发人员就直接会去选择View去处理。但是如果从性能角度考虑,这层遮盖层仅仅是只有遮盖功能,并没有事件的响应以及其他复杂业务逻辑的功能,这边考虑的是用layer来处理,如下所示:

layer来处理的话,有个问题会出现,即对layer身上没有tag标签可以标记,所以对于初次展示的遮盖依然需要用View来遮盖(即红色遮盖的部分),用户只要点击过该行之后,就是下面的Layer(灰色遮盖)。
灰色遮盖Layer会长期存在,而红色遮盖View则会在用户点击了改行之后就会永远消失(红色遮盖类似标记用户已读未读的功能)。

3.手势添加的策略
手势添加是个小问题,重要的是手势添加之后如何和View关联处理的逻辑,所以这里就只展示手势点击后的策略,即如下所示:

1.文字行数计算的细节
首先是关于文字的高度计算特点,由于系统默认的Label是没有纵向居中展示的功能,所以这里继承了MyLabel的自定义Label,来实现自己的Label可以居上显示,从而可以在后续为遮盖层实现精准覆盖到对应的文字上。
这也算是站在巨人的肩膀上做开发了哈!

2.文字行数计算的说明
如下所示,关于文字行数的计算,这里的注释写的很明白!为了方便大家理解,这里就再以一个案例来聊聊,这里注意的细节。
首先如图的singleSize为单个文字的高度。注意这里传的字典中一定不要有行高传过去,不然后续计算就比较麻烦。
另外一点就是 如图的lineCount == 1的时候为什么还要加上个行高和实际字体高度的比较呢?

核心原因是因为一行单纯文字假设是20高度,行高10,则行高为30。那么一行文字展示为30,而二行文字展示为20+10+20=50,此时用一行文字30/行高30 = 1,而二行文字50/30 得到的integer数值依然为1。所以就必须要进一步文字的高度和行高是不是刚好。但考虑文字的高度比如本次用的是18号文字,字高位21.xxxx。这样的情况。不知道其他的文字和行高会不会出现后面有误差的情况。此时倘若文字的高度大于行高倒还好说。因为结果是1.多,即为1;而反之的话,为0.9多,就会出现行数为0的尴尬情形。
所以后续在进行行数计算的时候,实际也是考虑了以上的情形, 在计算出来的lineCount基础上加1.因为最后一行是没有行间距的。如下所示实际的行数为lineCount + 1。

2.动态计算一片字所占方法的枚举
这块分析和研究方面情况容易忽略,顺手说一下,因为在后面其他地方有遇到过这样的问题,即如下所示,在Label的boundingRectWithSize方法中有options,是来让我们告诉系统,你想要获得这串文字的整块的布局还是说是某一行甚至某一个字的大小返回情况。
这块个人写了2个方法如下所示,Demo中没有,一个是返回一块文字的尺寸,一个是返回一行文字的尺寸。核心是options值的不同。

4.小不足点1个
如下所示的,在点击手势中由于无法监听到其结束时的状态,所以用长按手势来代替。即对于点击手势它的gesture.state只有UIGestureRecognizerStateBegan的状态,那么问题如果非要用点击手势,就会出现,用户点击后,无法监听到其点击手势结束时把对应点击位置的Layer给显示出来的逻辑,所以考虑用长按手势来代替,只是把长按时间如下设置为0.05s。
所以如果发现有这块秒速的点击无法出现效果,还望大家一起思考这个问题的解决方案,谢谢!

过去3年多以来,由于制定了很多计划,但由于各种原因所致,技术的学习时有时无。
就像一个笑话说的,我们有很多计划,简称为plan。但在实际完成过程中只完成了个p,因为lan,哈哈哈!
希望未来可以重新开启技术之窗的对话,欢迎大家捧场哈!
这里附上一个gitee的项目连接地址: 我的富文本之DDRichTextDemo
一并把一些参考资料附上:
1.iOS富文本(NSAttributedString)---尽力弄全了
2.iOS开发之UILable文字 居上对齐/居中对齐/居下对齐
3.IOS如何使用CAShapeLayer实现复杂的View的遮罩效果

有问题欢迎评论区见哈!

以上是关于iOS富文本Label实现点击事件,类似Word在横线上输入编辑的主要内容,如果未能解决你的问题,请参考以下文章

iOS富文本实现列表显示效果

免费JS富文本编辑器 总有一款会适合你

iOS富文本实现(-):私密阅读效果

iOS中文行间距富文本高度与显示那些坑

iOS踩过的坑之富文本计算文字高度

百度富文本编辑器支持从word复制粘贴保留格式和图片的插件