ios捕捉移動view的點選事件
阿新 • • 發佈:2019-01-11
對Core Animation來說,不管是顯式動畫還是隱式動畫,對其設定frame都是立即設定的,比如說給一個UIView做移動動畫,雖然看起來frame在持續改變,但其實它的frame已經是最終值了,這種情況下,哪怕這個UIView是UIButton的例項,其觸發touch事件的範圍還是最終frame的地方。比如一個Button的frame是(0,0,100,100),要把它從0,0移動到200,200,在這種情況下:
如果我們要為移動動畫中的View新增touch事件,就需要在後面用到hitTest。我們先建立一個動畫Layer: [objc]
view plain
copy
print?
左邊是先設定的anchorPoint再設定frame,右邊是相反,可以看到如果是先設定anchorPoint的話,在剛開始就能得到正確的結果,即position為0,0。但如果是設定bounds的話就不用這麼麻煩了,順序無所謂。我在這裡之所以要設定anchorPoint,是因為在後面的CAKeyframeAnimation將用position來做動畫,如果anchorPoint為預設值(即0.5,0.5)的話,在動畫中將會出現一個x、y軸一半的偏移,就像這樣:
下面用一張圖解釋anchorPoint的取值:
position是以anchorPoint為原點的,預設這個原點在中心位置,自然就會出現上圖x、y軸的偏移,其實只要我在動畫中將position做個偏移就不用設定anchorPoint,但是我覺得動畫從0到終點更直觀一些,所以這才是我設定anchorPoint的原因,並不是說非設不可。最後用一個weak屬性引用動畫Layer並把這個Layer新增到self.view.layer中。 接下來是動畫部分: [objc] view plain copy print?
接下來為self.view新增手勢識別: [objc] view plain copy print?
- 如果你使用的是顯式動畫(CAKeyframeAnimation和CABasicAnimation),是通過指定path或values來進行動畫的,它的frame並沒有改變,touch範圍還是(0,0,100,100)這個範圍內
- 如果你使用的是隱式動畫(UIView的animate方法),是通過設定frame來進行動畫的,那麼它的touch範圍就是(200,200,100,100)這個範圍內
這個區別很重要,你只用記住,如果是用UIView做動畫,設定的frame是有效的; 如果CALaye做動畫設定的frame是無效的,你應該在動畫結束後顯式地指定position的值 |
如果我們要為移動動畫中的View新增touch事件,就需要在後面用到hitTest。我們先建立一個動畫Layer: [objc]
- CGSize layerSize = CGSizeMake(100, 100);
- CALayer *movingLayer = [CALayer layer];
- movingLayer.bounds = CGRectMake(0, 0, layerSize.width, layerSize.height);
- [movingLayer setBackgroundColor:[UIColor orangeColor].CGColor];
- movingLayer.anchorPoint = CGPointMake(0, 0);
- [self.view.layer
- self.movingLayer = movingLayer;
左邊是先設定的anchorPoint再設定frame,右邊是相反,可以看到如果是先設定anchorPoint的話,在剛開始就能得到正確的結果,即position為0,0。但如果是設定bounds的話就不用這麼麻煩了,順序無所謂。我在這裡之所以要設定anchorPoint,是因為在後面的CAKeyframeAnimation將用position來做動畫,如果anchorPoint為預設值(即0.5,0.5)的話,在動畫中將會出現一個x、y軸一半的偏移,就像這樣:
下面用一張圖解釋anchorPoint的取值:
position是以anchorPoint為原點的,預設這個原點在中心位置,自然就會出現上圖x、y軸的偏移,其實只要我在動畫中將position做個偏移就不用設定anchorPoint,但是我覺得動畫從0到終點更直觀一些,所以這才是我設定anchorPoint的原因,並不是說非設不可。最後用一個weak屬性引用動畫Layer並把這個Layer新增到self.view.layer中。 接下來是動畫部分: [objc] view plain copy print?
- CAKeyframeAnimation *moveLayerAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
- //moveLayerAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
- //moveLayerAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(320 - self.movingLayer.bounds.size.width, 0)];
- moveLayerAnimation.values = @[[NSValue valueWithCGPoint:CGPointMake(0, 0)],
- [NSValue valueWithCGPoint:CGPointMake(320 - self.movingLayer.bounds.size.width, 0)]];
- moveLayerAnimation.duration = 2.0;
- moveLayerAnimation.autoreverses = YES;
- moveLayerAnimation.repeatCount = INFINITY;
- moveLayerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
- [self.movingLayer addAnimation:moveLayerAnimation forKey:@"move"];
接下來為self.view新增手勢識別: [objc] view plain copy print?
- ........
- self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];
- [self.view addGestureRecognizer:self.tapGesture];
- }
- -(void)click:(UITapGestureRecognizer *)tapGesture {
- CGPoint touchPoint = [tapGesture locationInView:self.view];
- if ([self.movingLayer.presentationLayer hitTest:touchPoint]) {
- NSLog(@"presentationLayer");
- }
- }
- Layer Tree
- Presentation Tree
- Render Tree