iphone - 使用 UIView 动画处理一系列动画的最佳方式

标签 iphone ios objective-c uiviewanimation uicolor

我正在构建一个 iOS 应用程序,其中我需要通过选择颜色将 View 的 backgroundColor 设置为动画。在我的 viewDidLoad 方法中,我基本上使用以下方法触发了一系列 UIView 动画。

-(void) beginFirstStageBackgroundAnimation
{
    [UIView animateWithDuration: 3.0f
                          delay: 3.0f
                        options: UIViewAnimationOptionTransitionCrossDissolve
                     animations:^{
                         self.view.backgroundColor = [UIColor colorWithRed: 251./255 green:203./255 blue:147./255 alpha:1.0];
                     }
                     completion:^(BOOL finished){
                         [self secondStageBackgroundAnimation];
                     }
     ];
}

完成处理程序触发包含下一个颜色的第二个方法....

-(void) secondStageBackgroundAnimation
{
    [UIView animateWithDuration: 3.0f
                          delay: 3.0f
                        options: UIViewAnimationOptionTransitionCrossDissolve
                     animations:^{
                         self.view.backgroundColor = [UIColor colorWithRed:251./255 green:224./255 blue:96./255 alpha:1.0];
                     }
                     completion:^(BOOL finished){
                         [self thirdStageBackgroundAnimation];
                     }
     ];
}

依此类推......这一直持续到第七个动画我调用 [self beginFirstStageBackgroundAnimation]; 在完成中再次开始该过程。

当我使用后退按钮离开 View 时,在 viewDidDisappear 中或当显示器上的计时器结束时,我运行 [self.view.layer removeAllAnimations]; 以完全摆脱动画。然而,该应用程序运行和工作完全符合预期,但在离开 View 并运行整个过程后似乎崩溃了,虽然我不知道为什么,但它似乎与此动画链有关。

是否有更好的解决方案来每 3 秒为 View 的 backgroundColor 设置动画并延迟 3 秒?

[self.view.layer removeAllAnimations]; 是否真的按照我的意愿行事?

编辑:我离开 View 的代码如下:

-(void) backBtnPressed:(id)sender
{
    [self stopAudio]; // stop audio that is playing.
    [self.view.layer removeAllAnimations]; // remove all animations?
    [self.navigationController popViewControllerAnimated: YES]; // pop view from stack
}

最佳答案

我认为要走的路是用参数表示您希望在每个动画中发生什么(在本例中只是一种颜色),然后将这些参数保存在一个数组中。该数组就像您的动画待办事项列表:

@property(strong, nonatomic) NSArray *animationTodo;

我们还需要跟踪我们在列表中的位置。使用盒装 (NS) 数字,这样我们就可以将“不要动画”表示为 nil,与索引零不同:

@property(strong, nonatomic) NSNumber *animationIndex;

数组用颜色初始化:

self.animationTodo = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], ... nil];

现在可以将动画压缩到一个方法中:

- (void)animate {

    if (!animationIndex) return;
    NSInteger index = [animationIndex intValue];
    [UIView animateWithDuration:3.0 animations:^{
        self.view.backgroundColor = [animationToDo objectAtIndex:index];
    } completion:^(BOOL finished) {
        NSInteger nextIndex = (index==self.animationTodo.count-1)? 0 : index+1;  // advance index in a ring
        self.animationIndex = [NSNumber numberWithInt:nextIndex];
        // schedule the next one in 3s
        [self performSelector:@selector(animate) withObject:nil afterDelay:3.0];
    }];
}

Perform selector 让您声明延迟,并且还具有积极的效果,即每次开始下一个动画时都不会结束堆栈。

现在停止也很简单。在 View 消失之前以及您希望停止的任何其他时间执行此操作。

- (void)stopAnimating {

    self.animationIndex = nil;
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}

关于iphone - 使用 UIView 动画处理一系列动画的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15575091/

相关文章:

ios - applicationDidBecomeActive 在 ViewController 加载后运行

iphone - 将下载的数据放入字典的最佳方法

iphone - 在保持触摸的同时按下时隐藏 UITabBar

iphone - 将 UIImage 传递给第二个 View Controller 会延迟转换

ios - iOS-AFNetworking GET方法中不兼容的 block 指针类型

ios - 如何在 View 加载时获取视频的第一帧?

ios - 'self' 未通过 Analyzer 设置为 '[(super or self) init…]' 的结果时使用的实例变量

ios - 错误域=com.alamofire.error.serialization.response 代码=-1011“请求失败 : bad request (400)

ios - iOS 7 上的 UINavigationBar Flash

ios - 触摸延迟开始 Cocos2d iOS