1

我尝试使用以下代码将图像视图添加到 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
4

5 回答 5

7

使用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];

您的 methodToAddImages 看起来像:

- (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 还是 Manual Retain Release,但这个答案是假设 ARC 编写的(基于您问题中的代码)。

于 2013-07-18T19:09:58.433 回答
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];
    });
}
于 2013-07-18T19:14:19.560 回答
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,您不必担心会使计时器失效,也不会有让计时器在内存中运行的风险。

于 2013-07-18T19:14:00.427 回答
2

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

 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];
于 2016-05-06T06:35:09.743 回答
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;
}
于 2013-07-18T19:18:23.967 回答