对Core Animation来说,不管是显式动画还是隐式动画,对其设置frame都是立即设置的,比如说给一个UIView做移动动画,虽然看起来frame在持续改变,但其实它的frame已经是最终值了,这种情况下,哪怕这个UIView是UIButton的实例,其触发touch事件的范围还是最终frame的地方。比如一个Button的frame是(0,0,100,100),要把它从0,0移动到200,200,在这种情况下:
1.如果你使用的是显式动画(CAKeyframeAnimation和CABasicAnimation),是通过指定path或values来进行动画的,它的frame并没有改变,touch范围还是(0,0,100,100)这个范围内
2.如果你使用的是隐式动画(UIView的animate方法),是通过设置frame来进行动画的,那么它的touch范围就是(200,200,100,100)这个范围内
这个区别很重要,你只用记住,如果是用UIView做动画,设置的frame是有效的;
如果CALaye做动画设置的frame是无效的,你应该在动画结束后显式地指定position的值
self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];
[self.view addGestureRecognizer:self.tapGesture];
}
动画的过程只是看起来是动态变换的,其内部的值已经是固定的了。
简单说下Core Animation,Core Animation用三个Tree来完成动画:
Layer Tree
Presentation Tree
Render Tree
-(void)click:(UITapGestureRecognizer *)tapGesture {
CGPoint touchPoint = [tapGesture locationInView:self.view];
if ([self.movingLayer.presentationLayer hitTest:touchPoint]) {
NSLog(@"presentationLayer");
}
}

Layer Tree用来存储Layer最终的值,即不考虑动画的发生,你只要对一个Layer进行了一些诸如backgroundColor、position、alpha之类的赋值,其Layer Tree中存储的值立刻改变;Presentation Tree用来存储所有的要在动画过程中显示的值,与Layer Tree相反;Render Tree专门用来渲染Presentation Tree中的值,也是与Core Animation交互的唯一纽带,这一过程被系统隐藏了,我们不用管也没办法管。
这就是说Layer Tree与Presentation Tree其实都相当于是模型对象,只存储Layer的状态,当我们要读取动画进行中的状态的时候,调用layer的presentationLayer属性就可以了,这个属性从Presentation Tree中返回代表当前动画状态的Layer,接下来调用Layer的hitTest方法就能判断是不是一次有效点击了。
locationInView:与translationInView:的区别
translationInView : 手指在视图上移动的位置(x,y)向下和向右为正,向上和向左为负。
locationInView : 手指在视图上的位置(x,y)就是手指在视图本身坐标系的位置。
velocityInView: 手指在视图上移动的速度(x,y), 正负也是代表方向,值得一体的是在绝对值上|x| > |y| 水平移动, |y|>|x| 竖直移动。
网友评论