Autolayout与CATransform3D共同使用引发的问题解决
来源:互联网 发布:mysql主从同步原理 编辑:程序博客网 时间:2024/05/21 09:23
0x00
最近项目中需要实现类似Tinder的翻牌效果。基本思路是自定义一个ContainerView,上面加入几个自定义的卡片(view),监听touch动作,根据手指移动的距离控制卡片的转动角度。手指离开屏幕后,如果移动距离大于门限值,将其remove,并从复用队列中加入新的卡片。
实现起来并不复杂,卡片的布局是使用Autolayout构建的。卡片的翻转通过如下代码实现
view.layer.transform=CATransform3DMakeRotation(angle,0,0,1);
但是在对subView翻转角度时,却产生了一个奇怪的问题。如图1.1所示,在卡片转动的时候,子视图居然出现的了放大的效果。所有的约束设置都没有问题,为什么会出现这种情况呢?
通过查官方文档发现,改变transform属性时,实际上已经永久改变的view的位置。而当一个view的角度发生变化时,它的frame值也随之发生变换。
图1.2中紫色方框代表一个旋转的view,绿色方框是前者的superView。由图可见,旋转后的view转换到superView后,frame被放大了。而transform属性每一次改变都会触发Autolayout的重绘。因而出现了图1.1所示的效果。
0x01
那么改怎么解决呢?一种方法是使用手码创建卡片视图,用frame写死大小。或者将卡片视图放入一个容器视图中,容器视图固定大小。
但是由于业务需求的问题,这几种方案都不合适。为了实现旋转效果并不改变视图的大小,很容易想到Core Animation。Core Animation动画不会改变视图本身的大小。官方文档是这样描述的:
It achieves this behavior by caching the contents of views into bitmaps that can be manipulated directly by the graphics hardware.
他实际上操作的是layer维护的bitmaps缓存。现在我们使用CoreAnimation试试效果。
CABasicAnimation* ba = [CABasicAnimationanimationWithKeyPath:@"transform"];
ba.duration=0.15;
ba.toValue= [NSValuevalueWithCATransform3D:CATransform3DMakeRotation(angle,0,0,1)];
[view.layeraddAnimation:baforKey:nil];
没错,现在子视图已经不放大了。但还有点小问题,滑动过程中会有点颤抖的感觉。
这是因为动画时间只有0.15秒,当手指放在屏幕上不动时,动画结束,卡片又回到了原来的状态。
CALayer中存在三个tree,他们分别是:
Model Tree
Presentation Tree
Render Tree
Model Tree代表CALayer的真实属性,Presentation Tree对应动画过程中的属性。无论动画进行中还是已经结束,Model Tree都不会发生变化,变化的是Presentation Tree。而动画结束后,Presentation Tree就被重置回到了初始状态。为了让其保持旋转状态,需要在加两句代码:
ba.fillMode=kCAFillModeForwards;
ba.removedOnCompletion=NO;
好了,现在终于不抖了。
注意:即使我们设置了removedOnCompletion = NO,其Model Tree依然不变。要回到初始状态只需调用layer的removeAllAnimations方法就可以复原了。
- Autolayout与CATransform3D共同使用引发的问题解决
- 多线程共同使用一个锁引发的死锁问题
- OcclusionQuery与pssm的共同使用
- a标签的href属性和onclick事件共同使用可能引发的问题
- Ios中CATransform3D的一点使用心得。
- 关于使用eventbus引发的NoClassDefFoundError问题解决方案
- Git 的使用,与git和github共同使用
- python与linux共同修改ini配置文件时的空格、注释等问题解决办法
- PhoneFactory.getDefaultPhone()引发的问题解决
- PhoneFactory.getDefaultPhone()引发的问题解决
- PhoneFactory.getDefaultPhone()引发的问题解决
- PhoneFactory.getDefaultPhone()引发的问题解决
- PhoneFactory.getDefaultPhone()引发的问题解决
- NGUI与GUIText共同使用的解决办法【原创】
- 迭代器和集合共同操作引发的异常
- AutoLayout的基本使用
- autolayout的使用
- 使用AutoLayOut的注意事项
- Android项目——Spinner的使用
- 数据结构例程——简单的计数排序
- 第七周实践项目5—排队看病模拟
- NEUOJ 1660 (容斥+矩阵)
- 通过ThreadLoad实现线程范围内的共享变量
- Autolayout与CATransform3D共同使用引发的问题解决
- Android 各国语言缩写及简称详细介绍
- JS温习:基础(一)变量,常量,数据类型
- OC学生成绩管理类(三 Student学生类)
- JS温习:基础(二)运算符
- 当优秀成为了一种习惯,坚持又算得了什么——英语总结
- 堆排列
- MapReduce 矩阵乘法
- linux下字符串处理工具二:awk( 二),awk脚本