0

さて、コードに問題があります。imageViewersを使用してゲームのようなグリッドを作成したいのですが、imageViewersがどのように画像を変更するかをメソッドが実行すると、それを行う行が実際に実行されたときではなく、実行が終了したときにのみ画面/imageviewersが更新されます。無限ループを含むメソッドがあり、ボタンを押すと imageViewers の画像が変更されます。ボタンは、ブール変数を true に変更するメソッドを呼び出すため、メインのゲーム ループは、特定の変数が true かどうかを常にチェックすることで、何が押されたかを認識します。しかし、ゲーム ループが終了しないため、画面が更新されることはありません。実行中に画面の内容を更新する方法はありますか?

このコードを使用して、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 のカテゴリ メソッドにすることもできます。次のように呼び出します。

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 に答える