【问题标题】:Playing animations in sequence in objective c在目标 c 中按顺序播放动画
【发布时间】:2018-07-06 22:07:14
【问题描述】:

我正在尝试按顺序播放动画,但在播放它们时遇到问题,因为 for 循环遍历数组中的对象列表。

它会在数组中移动,但不会播放每一个,而是播放最后一个。

-(void) startGame {
    gramma.animationDuration = 0.5;

    // Repeat forever
    gramma.animationRepeatCount = 1;
    int r = arc4random() % 4;
    [colorChoices addObject:[NSNumber numberWithInt:r]];

    int anInt = [[colorChoices objectAtIndex:0] integerValue];
    NSLog(@"%d", anInt);
    for (int i = 0; i < colorChoices.count; i++) {

        [self StrikeFrog:[[colorChoices objectAtIndex:i] integerValue]];
        //NSLog(@"%d", [[colorChoices objectAtIndex:i] integerValue]);
        sleep(1);

    }
}

它在整个周期中移动得非常快,而 sleep 并没有做任何事情来让它播放每个动画......有什么建议吗?

【问题讨论】:

    标签: ios animation


    【解决方案1】:

    使用 NSTimer 以便运行循环有时间处理。直到 startGame 返回后才开始绘制。

    编辑:

    -(void) myTimerMethod:(NSTimer *)inTimer {
      if ( mPosition < [colorChoices count] ) {
        [self StrikeFrog:[[colorChoices objectAtIndex:mPosition] integerValue]];
        mPosition += 1;
      } else {
        [inTimer invalidate];
      }
    }
    

    启动它:

    mPosition = 0;
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(myTimerMethod:) userInfo:nil repeats:YES];
    

    如果您需要能够在中途停止计时器,请保留对它的引用,以便您可以根据需要使其无效。

    【讨论】:

    • 嗯,我该怎么做?我看过一些 NSTimer 示例,但我还没有学会正确使用它,呵呵。虽然这确实有点道理。因为它只播放序列中的最后一个动画,我觉得有点烦人。计时器必须在循环内运行还是作为某种类型的全局计时器运行?
    • 我查阅了一些文档,所以我认为您的意思是用计时器替换 for 循环,然后在满足条件时使其无效?
    • 这看起来很棒!我现在没有我的mac,但我一定会试试这个^^
    【解决方案2】:

    我怀疑我知道出了什么问题,但不知道“正确”的解决方法,这取决于您想成为“正确”的程度。发生的事情很简单——Objective C 不调用函数,它传递消息。当您执行 [self StrikeFrog] 时,一条消息将被放置在队列中,待队列耗尽后立即执行;您可能会在最后收到所有消息,因为 StrikeFrog 在睡眠之前没有被调用 - 只要队列线程被解除阻塞,它就会被调用。例如,在单线程应用程序中,最终效果是休眠 (colorChoices.count) 秒,然后在退出 for 循环后执行所有 StrikeFrog 事件,因为这是事件队列第一次可以发送你的事件。换句话说,无论使用多少线程,Obj C 中的所有“函数调用”都是异步的。

    我建议要么使用 C 进行低级,要么使用 CoreAnimation 进行高级。如果这些都不适合您,您可以尝试NSObject performSelector:withObject:afterDelay: 将一大堆事件排队,每个事件都会在一段时间后执行。不过,这种方法有很多问题需要解决,所以要小心。

    【讨论】:

    • drawnonward 的建议比 performSelector 更好 - 计时器允许您离开事件队列,稍后再回来将下一个事件放入队列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多