Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 暂停带有延迟动画的CALayer动画_Ios_Objective C_Uiview_Core Animation - Fatal编程技术网

Ios 暂停带有延迟动画的CALayer动画

Ios 暂停带有延迟动画的CALayer动画,ios,objective-c,uiview,core-animation,Ios,Objective C,Uiview,Core Animation,我有一套嵌套的UIView动画(在给定的时间有2到3层),我希望能够暂停并继续。其中一些动画使用-animateWithDuration:animations:completion:,而其他动画使用-animateWithDuration:delay:options:animations:completion:来延迟动画块的执行 我阅读并实现了关于暂停层树中所有动画的内容,但我遇到了使用延迟参数的动画的问题。我可以暂停并恢复动画,但当动画恢复时,任何具有与之相关联的延迟的动画块似乎都会将其延迟延

我有一套嵌套的
UIView
动画(在给定的时间有2到3层),我希望能够暂停并继续。其中一些动画使用
-animateWithDuration:animations:completion:
,而其他动画使用
-animateWithDuration:delay:options:animations:completion:
来延迟动画块的执行

我阅读并实现了关于暂停层树中所有动画的内容,但我遇到了使用延迟参数的动画的问题。我可以暂停并恢复动画,但当动画恢复时,任何具有与之相关联的延迟的动画块似乎都会将其延迟延长层树暂停的时间量。因此,例如,如果其中一个块的延迟为1秒,并且层树暂停了3秒,则动画在恢复后会延迟4秒。我猜这与
beginTime
属性有关?任何帮助都将不胜感激

// Pause and Resume methods, right from the technical Q&A
- (void)pauseAnimationsOnLayer:(CALayer *)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}

- (void)resumeAnimationsOnLayer:(CALayer *)layer
{
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0;
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

// Chained animations
- (void)animateNextPopup
{
    [UIView animateWithDuration:kRFPVictorySequenceStatePopupDuration
                     animations:^{
                         [_currentStateImageView setHidden:NO];
                         [_currentStateImageView setTransform:CGAffineTransformIdentity];

                     }
                     completion:^(BOOL finished) {
                         [UIView animateWithDuration:kRFPVictorySequenceStateSlideOffDuration
                                               delay:kRFPVictorySequenceStateVoteDelay
                                             options:UIViewAnimationOptionCurveEaseInOut
                                          animations:^{
                                              if (winnerIsDem) {
                                                  [_currentStateImageView setFrame:CGRectMake(-_currentStateImageView.frame.size.width, 
                                                                                              _currentStateImageView.frame.origin.y, 
                                                                                              _currentStateImageView.frame.size.width, 
                                                                                              _currentStateImageView.frame.size.height)];
                                              }
                                              else {
                                                  [_currentStateImageView setFrame:CGRectMake(1024, 
                                                                                              _currentStateImageView.frame.origin.y, 
                                                                                              _currentStateImageView.frame.size.width, 
                                                                                              _currentStateImageView.frame.size.height)];
                                              }
                                          }
                                          completion:^(BOOL finished) {
                                              // Do some stuff
                                          }
                          ];
                     }
     ];
}

我建议采用不同的方法

动画块易于实现,但仅在不需要对动画进行任何控制时才有用

否则,应使用计时器手动创建自己的动画

[NSTimer scheduledTimerWithTimeInterval:0.1
                                 target:self
                               selector:@selector(timerFired)
                               userInfo:nil
                                repeats:YES];

- (void)timerFired
{
    if (isPaused) {
        // Do nothing
    } else {
        // Animate
    }
}

- (IBAction)pauseTapped:(id)sender
{
    if (isPaused) {
        isPaused = NO;
    } else {
        isPaused = YES;
    }
}

isPaused
是控制动画状态的标志。

我找到了问题的解决方案!必须在动画的完成块中将self.layer.beginTime值重置为零

e、 g

暂停/恢复代码的其余部分保持完全相同


最好的

谢谢你的回复,但是这个想法其实也有它自己的问题。使用标准的
NSTimer
不会将动画与设备的显示速率同步,这可能会导致动画看起来不稳定。最好使用类似的
CADisplayLink
,但其设计完全是为了与显示器同步。不过,使用一个显示链接对象来运行10个序列化动画可能会产生一些严重的意大利面代码。最后,我的问题是,为什么在层树中暂停动画会影响后续动画的延迟值?看起来很奇怪,不是吗?“一些严肃的意大利面代码”。。。是的,你是对的。。。但毕竟我是意大利人;)该死,我希望这能奏效。。。但对我来说没有:(,没有效果。现在我决定通过动画块来消除延迟。@cclogg如果在同一层上运行多个块动画,则必须设置一次,而不是在每个块动画中:)
[UIView animateWithDuration:element.duration 
                      delay:element.delay 
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                      // Animate properties here!
                     }
                 } completion:^(BOOL finished){
                              // Reset BeginTime all the time
                              // So, in case a pause took place the delay values are valid again!
                         **self.layer.beginTime = 0.0f;**
                 }];