如何在循环中添加延迟?

时间:2013-07-18 19:03:36

标签: ios objective-c loops uiimageview

我尝试使用以下代码将图像视图添加到UIView:

for (int i = 0; i <numberOfImages; i++) {
    UIImageView *image = [UIImageView alloc]initWithFrame:CGRectMake(40, 40, 40, 40)];
    image.image = [images objectAtIndex:i];
    [self.view addSubview:image];
}

这样可行,但问题是我希望在添加每个图像之前有5秒的延迟,而是将它们全部添加到同一时间。有人可以帮帮我吗?感谢。

示例:

5 seconds = one image on screen
10 seconds = two images on screen
15 seconds = three images on screen

5 个答案:

答案 0 :(得分:6)

使用NSTimer会更有效。

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:numberOfSeconds
                                                      target:self 
                                                    selector:@selector(methodToAddImages:) 
                                                    userInfo:nil 
                                                     repeats:YES];

这将基本上以指定的时间间隔重复调用methodToAddImages。要停止调用此方法,请调用[NSTimer invalidate](请记住,无效的计时器无法重复使用,如果要重复此过程,则需要创建新的计时器对象。)

methodToAddImages内,你应该有代码来遍历数组并添加图像。 您可以使用计数器变量来跟踪索引。

另一个选项(我的建议)是拥有此数组的可变副本并添加lastObject作为子视图,然后将其从数组的可变副本中删除。

您可以通过首先按相反顺序制作mutableCopy来执行此操作,如下所示:

NSMutableArray* reversedImages = [[[images reverseObjectEnumerator] allObjects] mutableCopy];

您的方法ToAddImages看起来像:

- (void)methodToAddImages
{
    if([reversedImages lastObject] == nil)
    {
        [timer invalidate];
        return;
    }

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRectMake(40, 40, 40, 40))];
    imageView.image = [reversedImages lastObject];
    [self.view addSubview:imageView];
    [reversedImages removeObject:[reversedImages lastObject]];
}

我不知道您是使用ARC还是手动保留版本,但这个答案是在假设ARC的基础上编写的(基于您问题中的代码)。

答案 1 :(得分:4)

您可以使用dispatch_after来分派一个块,异步执行以添加图像。示例:

for(int i = 0; numberOfImages; i++)
{
    double delayInSeconds = 5.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
    {
        UIImageView *image = [UIImageView alloc]initWithFrame:CGRectMake(40, 40, 40, 40)];
        image.image = [images objectAtIndex:i];
        // Update the view on the main thread:
        [self.view performSelectorOnMainThread: @selector(addSubview:) withObject: image waitUntilDone: NO];
    });
}

答案 2 :(得分:2)

将您的代码分成一个函数,然后通过NSTimer调用。

for (int i = 0; numberOfImages; i++) {
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5
                                                      target:self
                                                    selector:@selector(showImage)
                                                    userInfo:[NSNumber numberWithInt:i] 
                                                     repeats:NO];

然后你的功能:

-(void) showImage:(NSTimer*)timer {
      //do your action, using
      NSNumber *i = timer.userInfo;

      //Insert relevant code here

      if (!done)
          NSTimer *newTimer = [NSTimer scheduledTimerWithTimeInterval:5 
                                                      target:self
                                                    selector:@selector(showImage)
                                                    userInfo:[NSNumber numberWithInt: i.intValue+1]
                                                     repeats:NO];
  }
}

userInfo是将参数传递给需要调用的函数的便捷方式(但它们必须是对象)。此外,通过使用repeats:NO,您不必担心计时器无效,并且不存在让计时器在内存中运行的风险。

答案 3 :(得分:1)

我认为你最好用动画

for (int i = 0; i < numberOfImages; i++)
{
    // Retrieve the image
    UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(40, 40, 40, 40)];
    image.image = [images objectAtIndex:i];

    // Add with alpha 0
    image.alpha = 0.0;
    [self.view addSubview:image];

    [UIView animateWithDuration:0.5 delay:5.0*i options:UIViewAnimationOptionAllowUserInteraction animations:^{
        // Fade in with delay
        image.alpha = 1.0;
    } completion:nil];
}

不完全符合您的要求,因为所有视图都会立即添加,然后淡入,但我觉得您实际上是在尝试实现这一点,就像某种图像堆叠一样,对吧?

事实上,如果您计划删除上一张图片,可以在完成块中执行此操作,如下所示:

UIImageView *imagePrevious = nil;

for (int i = 0; i < numberOfImages; i++)
{
    // Retrieve the image
    UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(40, 40, 40, 40)];
    image.image = [images objectAtIndex:i];

    // Add with alpha 0
    image.alpha = 0.0;

    [UIView animateWithDuration:0.5 delay:5.0*i options:UIViewAnimationOptionAllowUserInteraction animations:^{
        // Add and fade in with delay
        [self.view addSubview:image];
        image.alpha = 1.0;
    } completion:^(BOOL finished)
    {
        if (finished && imagePrevious)
        {
            [imagePrevious removeFromSuperview];
        }
    }];

    imagePrevious = image;
}

答案 4 :(得分:1)

这也是最好的选择。试试这个

 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];