Frame与动画导致的bug
这边记录一些开发中碰到的相应bug,并记录相对应的解决方式。项目中相应的问题碰到了两次,最近一次碰到相应的bug,排查了挺久最后想起来之前开发的时候碰到的问题,所以这边做下记录。本文中因为碰到的bug是修改frame与旋转动画导致的,后面有看到其他动画引起相似的bug。具体的可以
1、多次修改frame与旋转
项目版本需求中,数据结构中设计了旋转角度,但是由于前期没有使用到相应的属性,所以没有发现该bug。在后续的风格增加中出现了相应的bug。多次设置frame后设置旋转,导致视图非自己想要的效果。
问题分析:由于多次修改了frame,无法确定每次修改是否都是在旋转之前。而且为了保证都是在旋转之前修改frame可能会涉及到比较多的逻辑问题,所以这边的处理方式是给旋转增加异步主线程
,代码如下如下:
- (void)setLayerRotateAngle:(CGFloat)angle layerView:(UIView *)layerView {
if (angle > 0) {
//顺时针旋转75度,M_PI为180度,要逆时针为 -Degree
double degree;
if (angle <= 180) {
degree = angle / 180.0;
} else {
degree = - angle/180.0;
}
dispatch_async(dispatch_get_main_queue(), ^{
CGAffineTransform transform= CGAffineTransformMakeRotation(M_PI * degree);
layerView.transform = transform;//旋转
});
}
}
异步主线程
只需要确保设置旋转的代码放在最后面就能防止修改frame出现在旋转之后,需要等待异步主线程
之前的代码执行完毕才会执行该方法。
主要根源是在旋转后修改了frame,所以需要根据这个根源来解决,所有修改都放在旋转之前,旋转之后就不修改frame。
当然也有人说为啥不用约束,emmm...只能说是项目中的需求使用frame会优于使用约束来实现相应的需求,使用约束上会相对的麻烦,因为每一个层都是由服务器下发,然后App端根据数据来创建的。
2、旋转后修改frame
由于项目中增加了新的需求需要在原本的功能上增加一个双击然后使得页面缩放的需求。一不小心又走入了之前的bug,或者说对之前的bug理解的不够透彻吧。
好吧~~~又费了一堆时间来排查...上面已经讲得够多了,这边就简单说一下解决方式吧。既然不能在旋转之后修改frame,那我是不是能够在修改frame之前先使得视图还原,然后在修改frame,最后使得视图重新旋转。
最后的验证是OK的...,附上代码:
// 如果需要旋转,则先还原角度
if (self.layerModel.base.angle > 0) {
self.transform = CGAffineTransformIdentity;
}
CGRect tmpFrame = ZTGEBookConvertFrameToApp(layerRect, self.mainBundle, self.pageWidth);
self.frame = tmpFrame;
self.alpha = 1.0;
// 设置视图旋转
[self setLayerRotateAngle:self.layerModel.base.angle layerView:self];
总结
对于动画后设置frame的问题还是需要慎重点,需要考虑下是否会引起相应的问题。