如何给循环添加一个延迟?

我试图使用此代码添加图像视图到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 

使用NSTimer会更有效率。

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

这将基本上以指定的时间间隔重复调用methodToAddImages 。 要阻止这个方法被调用,调用[NSTimer invalidate] (注意无效的定时器不能被重用,如果你想重复这个过程,你需要创build一个新的定时器对象)。

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

另一个选项(我的build议)是有一个这个数组的可变副本,并将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或手动保持版本,但是这个答案是假设ARC(基于你的问题中的代码)编写的。

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

 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]; }); } 

把你的代码分解成一个函数,然后通过NSTimer调用。

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

然后你的function:

 -(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 ,您不必担心使定时器无效,并且不会让定时器在内存中运行。

我想你会用animation更好

 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; } 

这也是最好的select。 尝试这个

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