当应用程序进入前台时,如何重新启动基于块的动画?

Posted

技术标签:

【中文标题】当应用程序进入前台时,如何重新启动基于块的动画?【英文标题】:How can I restart my block-based animation when the application comes to the foreground? 【发布时间】:2011-10-06 03:21:55 【问题描述】:

我有以下基于块的动画:

[UIView animateWithDuration:0.5f delay:0.0f 
                    options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse|UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseInOut
                    animations:^
                [view.layer setTransform:CATransform3DMakeScale(1.3f, 1.3f, 1.0f)];
                NSLog(@"animating");
                    completion:^(BOOL finished)
                        NSLog(@"Completed");
                    ];

当应用从后台返回时,将调用完成块,并且我的动画不会重新启动。我尝试使用以下委托方法重新启动动画:

- (void)applicationWillEnterForeground:(UIApplication *)application

    /*
     Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
     */
    [[self viewController] animate];
    ......

但这并不能恢复动画。

同样,我尝试了这些问题的答案中列出的方法:

ios, Restarting animation when coming out of the background

Restoring animation where it left off when app resumes from background

但是那里的建议都没有对我有用。当应用程序从后台返回时,还有其他方法可以恢复基于块的 UIView 动画吗?

【问题讨论】:

【参考方案1】:

朋友发现问题,需要在视图从后台返回时启用动画

- (void)applicationWillEnterForeground:(UIApplication *)application

    /*
     Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
     */
    [UIView enableAnimations:YES];
    [[self viewController] animate];
    ......

那么在block动画之前需要removeAllAnimations并设置layer.transform为Identity

hasStarted = YES;
    for(UIButton * button in goldenBreakOutButtons)
        for (UIView* view in button.subviews) 
            if (wasStarted) 
                [view.layer removeAllAnimations];
                view.layer.transform = CATransform3DIdentity;
            
            if ([view isKindOfClass:[UIImageView class]]) 
                [UIView animateWithDuration:0.5f delay:0.0f 
                        options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionRepeat
                        animations:^ 
                            [view.layer setTransform:CATransform3DMakeScale(1.3f, 1.3f, 1.0f)];
                            NSLog(@"animating");
                        
                        completion:^(BOOL finished)
                            if (finished) 
                                NSLog(@"Completed");
                            

                        ];
            
        
    

【讨论】:

你到底在哪里找到[UIView enableAnimations:YES]?我在任何地方都没有看到这种方法:( 有点晚了,但是试试 [UIView setAnimationsEnabled:YES];【参考方案2】:

请尝试在 ViewController 中订阅/取消订阅 标准(UIApplicationWillEnterForegroundNotification)通知 来自NSNotificationCenter

 

    -(void) loadView
    
    .....
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(restartAnimation)    
                                                 name:UIApplicationWillEnterForegroundNotification 
                                               object:nil];      
    ....
    
    
    - (void) viewDidUnload
    
    ...
      [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                      name:UIApplicationWillEnterForegroundNotification 
                                                    object:nil];
    ....
    
    
    -(void) dealloc
    
      [[NSNotificationCenter defaultCenter] removeObserver:self];
      [super dealloc];
    
    
    - (void) restartAnimation
    
        if(self.logoImageView)
        
            [logoImageView.layer removeAllAnimations];
            
            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    
            animation.fromValue       = [NSNumber numberWithFloat:1.0];
            animation.toValue         = [NSNumber numberWithFloat:0.6];
            animation.duration        = 1.5f;
            animation.timingFunction  = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
            animation.autoreverses    = YES;
            animation.repeatCount     = HUGE_VALF;
            
            [[logoImageView layer] addAnimation:animation forKey:@"hidden"];
        
    

 

【讨论】:

默认情况下它已经订阅,因为 UIApplicationWillEnterForegroundNotification 在应用程序返回前台之前被调用。

以上是关于当应用程序进入前台时,如何重新启动基于块的动画?的主要内容,如果未能解决你的问题,请参考以下文章

每次应用程序来自android的后台时启动第一个屏幕

重新加载页面上有哈希值

重新启动时如何使这个 CSS 关键帧动画平滑?

当活动从后台(暂停)到前台时重新创建 Android 活动

CoreData 仅在我重新启动应用程序后更新?

当应用程序关闭并重新启动时,如何继续上一个活动?