我可以以某种方式在 CAAnimation 的每个“tick”上执行一个块吗?它可能像下面的代码一样工作。如果有办法用选择器来做到这一点,那也是可行的。
NSString* keyPath = @"position.x";
CGFloat endValue = 100;
[CATransaction setDisableActions:YES];
[self.layer setValue:@(toVal) forKeyPath:keyPath];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath];
animation.duration = 1;
animation.delegate = self;
__weak SelfClass* wself = self;
animation.eachTick = ^{
NSLog(@"Current x value: %f", [wself valueForKeyPath:keypath]);
};
[self.layer addAnimation:animation forKey:nil];
典型的技术是使用显示链接(CADisplayLink
).
因此,为显示链接定义一个属性:
@property (nonatomic, strong) CADisplayLink *displayLink;
然后实现启动、停止和处理显示链接的方法:
- (void)startDisplayLink
{
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)stopDisplayLink
{
[self.displayLink invalidate];
self.displayLink = nil;
}
- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
CALayer *layer = self.animatedView.layer.presentationLayer;
NSLog(@"%@", NSStringFromCGRect(layer.frame));
}
请注意,当视图处于动画状态时,您无法查看其基本属性(因为它将反映最终目的地而不是“飞行中”位置),而是可以访问动画视图的图层的presentationLayer
,如上图所示。
无论如何,在开始动画时启动显示链接。并在完成后将其删除。
使用标准的基于块的动画,您可以执行以下操作:
[UIView animateWithDuration:2.0 delay:0 options:0 animations:^{
view.frame = someNewFrame;
} completion:^(BOOL finished) {
[self stopDisplayLink];
}];
[self startDisplayLink];
使用核心动画,它可能看起来像:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [NSValue valueWithCGPoint:startPoint];
animation.toValue = [NSValue valueWithCGPoint:endPoint];
[CATransaction setAnimationDuration:1.0];
[CATransaction setCompletionBlock:^{
[self stopDisplayLink];
}];
[CATransaction begin];
[self.animatedView.layer addAnimation:animation forKey:nil];
[CATransaction commit];
[self startDisplayLink];
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)