0

好的,我的代码有问题。我想使用 imageViewers 制作某种类似于游戏的网格,但是当更改 imageViewers 如何更改图片的方法时,它只会在完成执行后更新屏幕/imageviewers,而不是在实际执行它的行时更新。我有一个带有无限循环的方法,它会在您按下按钮时更改 imageViewers 的图片。按钮调用将布尔变量更改为真的方法,因此主游戏循环通过不断检查某些变量是否为真来知道按下了什么。但是因为游戏循环永远不会结束,所以屏幕永远不会更新。有没有办法在执行期间更新屏幕上的内容?

我正在使用此代码更改 imageViewers 内容:

     UIImage * white = [UIImage imageNamed: @"White.png"];
     UIImage * blue = [UIImage imageNamed: @"Blue.png"];
     int tagInt=1;
     for (int y = 0;y<10;y++){
         for (int x = 0;x<10;x++){
             UIImageView *imageView;
             imageView = [[UIImageView alloc] initWithImage:white];                 imageView.frame =CGRectMake(x*32,y*37,32,37);
             imageView.image = white;
             imageView.tag=tagInt;
             [self.view addSubview:imageView];
             tagInt++;
         }
     }
     for (int u = 1;u<20;u++){
         [NSThread sleepForTimeInterval:(1)];   
         UIImageView *g = (UIImageView*)[self.view viewWithTag:u];
         g.image =blue;
     }

这是一个人为的例子,因为我的实际代码太长,但有同样的问题。它仅在最后一个 for 循环(此延迟/线程睡眠命令)完成后在屏幕上更新,而不是在代码行执行时更新。

编辑:如果您需要任何上下文,这是项目:https ://www.dropbox.com/s/cvefllnhgj0tp6g/Stacker.zip

4

2 回答 2

3

在 iOS 中,所有与 UI 相关的东西都在主 (UI) 线程中完成。如果您有一个阻塞 ui 线程的操作 - 这意味着它会像您一样使线程保持忙碌 - 不会发生视图更新。所以你将不得不改变你的代码,你有一个“updateView”方法来改变图像视图的内容。必须定期调用此方法,例如使用 NSTimer 实例:https ://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html

假设更新视图的代码名为“updateView”,您可以像这样定义一个计时器:

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

因此,计时器每秒都会调用您的 updateView 方法,并且不会阻塞主线程,这将再次允许您对视图所做的更改变得可见。

于 2012-08-22T19:07:42.057 回答
1

我认为 CA 动画将满足您的需求。尝试这样的事情:

#import <QuartzCore/QuartzCore.h>

- (void)imageView:(UIImageView *)imageView crossfadeTo:(UIImage *)image duration:(NSTimeInterval)duration {

    [imageView.layer removeAnimationForKey:@"animateContents"];

    CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"];
    crossFade.duration = duration;
    crossFade.fromValue = (id)imageView.image.CGImage;
    crossFade.toValue = (id)image.CGImage;
    [imageView.layer addAnimation:crossFade forKey:@"animateContents"];

    imageView.image = image;
}

这也可以做成 UIImageView 上的 category 方法。像这样称呼它:

UIImage *white = [UIImage imageNamed: @"White.png"];
UIImage *blue = [UIImage imageNamed: @"Blue.png"];

UIImageView *imageView = [[UIImageView alloc] initWithImage:white];
[self imageView:imageView crossfadeTo:blue duration:5.0];

或者,这可以通过块动画以相同的方式调用它来完成,如下所示:

- (void)imageView:(UIImageView *)imageView crossfadeTo:(UIImage *)image duration:(NSTimeInterval)duration {

    UIImageView *fadeToImageView = [[UIImageView alloc] initWithFrame:imageViewFrame];
    fadeToImageView.image = image;
    [imageView.superview insertSubview:fadeToImageView belowSubview:imageView];

    [UIView animateWithDuration:duration animations:^{
        imageView.alpha = 0.0;
    } completion:^(BOOL finished) {
        imageView.image = image;
        imageView.alpha = 1.0;
        [fadeToImageView removeFromSuperview];
    }];
}
于 2012-08-22T19:26:37.113 回答