UITapGestureRecognizer *singleFingerOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerEvent:)]singleFingerOne.numberOfTouchesRequired = 1//手指数 singleFingerOne.numberOfTapsRequired = 1//tap次数
singleFingerOne.delegate = self
[label addGestureRecognizer:singleFingerOne]
UITapGestureRecognizer *singleFingerTwo = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerEvent:)]singleFingerTwo.numberOfTouchesRequired = 1
singleFingerTwo.numberOfTapsRequired = 2
singleFingerTwo.delegate = self
[label addGestureRecognizer:singleFingerTwo]
[singleFingerOne requireGestureRecognizerToFail:singleFingerTwo]//加这句话是为了出发双击事件时不响应单击事件。
项目当中要实现一个电子档案,效果呢是类似小说翻页的效果。很简单,先来说一下实现思路
写一个用来接收你想展示信息的控件,如果只是文字展示,那就label,如果带图片什么的,那就自定义一个view
然后就是左右滑动的手势,在左右手势实现方法中做数据判断展示,加上动画效果就ok 了
1、在self.view 上创建label
2、添加左右手势
3、根据左右手势实现方法,给 label.text 数组判断赋值
4、执行翻页动画
- ( void )viewDidLoad {
[ super viewDidLoad]
self .view.backgroundColor = [UIColor whiteColor]
_arr = @[@"11111", @"22222", @"33333",@"44444",@"55555"]
[ self buildLable]
[ self configTapGes]
_count=0
}
#pragma mark - label
- ( void )buildLable {
_labelView= [[UIViewalloc]init]
[ self .view addSubview:_labelView]
[_labelView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo( self .view.mas_centerX)
make.centerY.equalTo( self .view.mas_centerY)
make.width.mas_offset(WIDTH-40)
make.height.mas_offset(500)
}]
_labelView.backgroundColor = [UIColor orangeColor]
_label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, WIDTH-40, 500)]
_label.backgroundColor = [UIColor grayColor]
_label.numberOfLines = 0
_label.text = [_arr objectAtIndex:0]
[ self .labelView addSubview:_label]
}
#pragma mark - 手势
- ( void )configTapGes {
_fromRightSwip= [[UISwipeGestureRecognizeralloc]initWithTarget: self action: @selector (nextPage:)]
_fromRightSwip.direction = UISwipeGestureRecognizerDirectionLeft
[ self .view addGestureRecognizer:_fromRightSwip]
_fromLeftSwip= [[UISwipeGestureRecognizeralloc]initWithTarget: self action: @selector (forwardPage:)]
_fromLeftSwip.direction = UISwipeGestureRecognizerDirectionRight
[ self .view addGestureRecognizer:_fromLeftSwip]
}
#pragma mark - 下一页按钮响应事件
- ( void )nextPage:(UIButton*)btn {
if (_count<_arr.count-1) {
_label.text= [_arrobjectAtIndex:_count+1]
NSString*subtypeString
subtypeString =kCATransitionFromRight
[ self transitionWithType:@"pageCurl" WithSubtype:subtypeString ForView:_labelView]
_count=_count+1
} else {
_count=_arr.count-1
// [self showAlert:@"已经是最后一页"]
}
NSLog(@"下一页:%ld", ( long )_count)
}
#pragma mark - 上一页按钮响应事件
- ( void )forwardPage:(UIButton*)btn {
if (_count>0) {
_label.text= [_arrobjectAtIndex:_count-1]
NSString*subtypeString
subtypeString =kCATransitionFromLeft
[ self transitionWithType:@"pageCurl" WithSubtype:subtypeString ForView:_labelView]
_count=_count-1
} else {
_count=0
// [self showAlert:@"已经是第一页"]
}
NSLog(@"上一页:%ld", ( long )_count)
}
#pragma CATransition动画实现
/**
* 动画效果实现
*
* @param type 动画的类型 在开头的枚举中有列举,比如 CurlDown//下翻页,CurlUp//上翻页
,FlipFromLeft//左翻转,FlipFromRight//右翻转 等...
* @param subtype 动画执行的起始位置,上下左右
* @param view 哪个view执行的动画
*/
- ( void )transitionWithType:(NSString*) typeWithSubtype:(NSString*) subtypeForView: (UIView*) view {
CATransition *animation = [CATransition animation]
animation.duration=0.7f
animation.type= type
if (subtype != nil ) {
animation.subtype= subtype
}
animation.timingFunction = UIViewAnimationOptionCurveEaseInOut
[view.layeraddAnimation:animationforKey:@"animation"]
}
废话不多说,咱们直接先看效果!看是不是咱想要的哈
就像上图所示的示例:
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的遮罩效果
有问题欢迎评论区见哈!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)