【问题标题】:UIView animation completion block not being called未调用 UIView 动画完成块
【发布时间】:2014-09-16 16:13:15
【问题描述】:

我在正在开发的应用程序中发现了一个奇怪的错误。在我进入细节之前,我会陈述我的问题是

1 - 为什么不能调用 UIView 动画完成块

2 - 为什么 UIView 动画完成块会在模态视图出现后被调用?

我有一系列在视图控制器出现后开始的 UIView 动画。他们有完成块。大多数情况下,动画完成块都会被调用。但每隔一段时间,应用就会进入完成块不被调用的状态。

此外,当我从当前视图控制器模态显示新的视图控制器时,之前未调用的动画完成块都会被调用。

一旦应用处于这种状态,动画完成块就不会再被调用,除非我再次呈现模态视图。

我的动画块基本上是这样的:

 int i = 0;
 for (UIView *view in self.cellImageViews)
 {
     [UIView animateWithDuration:CELL_ANIMATION_DISMISS_DURATION
                           delay:(i)*CELL_ANIMATION_STAGGER_INTERVAL
                         options:UIViewAnimationOptionCurveEaseIn
                      animations:^{
                          view.transform = CGAffineTransformTranslate(view.transform, 0, CELL_ANIMATION_DISMISS_TRANSLATION);
                      } completion:^(BOOL finished) {
                         NSLog(@"Animation Completed: i:%d, finished:%d, count%d",i,finished,[self.oldCellImageViews count])
                         if(finished && (i == ([self.cellImageViews count]-1)))
                         {
                            NSLog(@"if statement passed");
                            // My completion block stuff goes here
                         } 
                       }             
         ];
        i++;
    }

【问题讨论】:

    标签: ios ios7 uiview objective-c-blocks uiviewanimation


    【解决方案1】:

    CALayer 动画不是排队,而是复合。在当前的方法中,您正在安排一些动画在一个或多个以前的动画没有机会完成之前开始。

    如果您绝对想排队 CALayer 动画,您还有其他选择,其中一些是:

    1. 在前一个动画的完成^块中触发新动画(链接)。
    2. 使用代理并在-animationDidStop:finished: 中触发新动画。
    3. 您可能会在紧要关头摆脱 UIViewAnimationOptionBeginFromCurrentState

    真正的解决方案是使用CALayer动画,而是使用CAAnimation

    【讨论】:

    • 我不确定我是否理解您的回答。是的,动画以交错的方式开始,是的,第二个动画在第一个动画完成之前开始,依此类推,这是我想要的行为。为什么这会阻止完成块被调用(为什么只是偶尔)?
    • 查看@NJGadhiya 的评论。这里的关键字是CALayerCAAnimation。您通过在同一对象上安排另一个CALayer 转换来中断给定对象上的CALayer 转换。如果您不想使用我概述的任何方法,也不想切换到CAAnimation,您可以通过在选项中添加UIViewAnimationOptionBeginFromCurrentState 来摆脱困境。
    【解决方案2】:

    尝试关注

    [UIView animateWithDuration:CELL_ANIMATION_DISMISS_DURATION
                          delay:(i)*CELL_ANIMATION_STAGGER_INTERVAL
                        options:UIViewAnimationOptionCurveEaseIn
                     animations:^{
                         int i = 0;
    
                         for (UIView *view in self.cellImageViews)
                         {
                             view.transform = CGAffineTransformTranslate(view.transform, 0, CELL_ANIMATION_DISMISS_TRANSLATION);
                             i++;
                         }
    
                     } completion:^(BOOL finished) {
                         if(finished)
                         {
                             NSLog(@"if statement passed");
                             // My completion block stuff goes here
                         }
                     }
     ];
    

    【讨论】:

    • 然后所有的单元格将同时动画,而不是按顺序开始。
    • 那么你必须使用CAAnimation
    猜你喜欢
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2013-02-13
    相关资源
    最近更新 更多