2

各ライトの座標を持つCGRectの配列を使用して、街のライトのアニメーションを実装しようとしています。次に、これらのCGRectの周りにUIViewを作成します。このロジック(このロジックを支援してくれたDarrenに感謝)は正常に機能していますが、アニメーションが完了すると、画面上の他のすべての要素(UIButton、スライダー、その他のUIImageViewなど)にアクセスできなくなります。スワイプジェスチャでさえ応答しません。アニメーションの前と最中は、すべての要素が適切に応答しますが、アニメーションが完了すると、すべての要素にアクセスできなくなります。[UIView bringSubviewToFront:]また、いくつかの要素を前面に表示して、それらにアクセスできるようにするのに役立つかどうかを確認しようとしましたが、役に立ちませんでした。バックグラウンドに送ってライトビューを作成しようとしても、それは問題ではないと思います [self.view sendSubviewToBack:light];アニメーションが完了すると、すべてにアクセスできなくなります。

誰かが私に何が欠けているのかを助けてくれる/提案してくれれば幸いです。

これが私のコードロジックとそれに対応する街の明かりのアニメーションのシーンです。rects&litsはivarsです。

ここに画像の説明を入力してください

- (void)viewDidLoad {
    pageCount=5;
    AVAudioSession * audioSession = [AVAudioSession sharedInstance];
    //Setup the audio session
    //...
    pageNum=1;
    //put imageviews in place
    //...
    //load a page
    [self loadPage];
    [self loadAudio];

    [self cityLightsSetUp];
    [super viewDidLoad];
}


-(void)loadPage{
    //Logic to load page...    
    /...
    if (pageNum == 3){
      [self startCityLights];
    }
}


- (void)cityLightsSetUp
{
    rects = [[NSMutableArray alloc] init];
    lit = [[NSMutableArray alloc] init];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(58, 217, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(71, 217, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(84, 217, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(97, 217, 10, 10)]];

    [rects addObject:[NSValue valueWithCGRect:CGRectMake(58, 231, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(71, 231, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(84, 231, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(97, 231, 10, 10)]];

    [rects addObject:[NSValue valueWithCGRect:CGRectMake(58, 245, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(71, 245, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(84, 245, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(97, 245, 10, 10)]];

    [rects addObject:[NSValue valueWithCGRect:CGRectMake(58, 258, 10, 10)]];
    [rects addObject:[NSValue valueWithCGRect:CGRectMake(71, 258, 10, 10)]];
}

- (void)startCityLights
{
    [self lightRandomLight];
    [self performSelector:@selector(switchOffRandomLight) withObject:nil afterDelay:1.0];
}

- (void)lightRandomLight
{
    BOOL escape = NO;
    int rand;

    while (!escape) {
        BOOL alreadyLit = NO;
        rand = arc4random() % [rects count];
        // Check if already lit
        for (UIView *view in lit) {
            CGRect litRect = view.frame;
            CGRect ranRect = [[rects objectAtIndex:rand] CGRectValue];
            if (CGRectContainsRect(litRect, ranRect)) {
                alreadyLit = YES;
            }
        }

        if (!alreadyLit) {
            UIView *light = [[UIView alloc] initWithFrame:[[rects objectAtIndex:rand] CGRectValue]];
            light.backgroundColor = [UIColor orangeColor];
            [lit addObject:light];
            [self.view addSubview:light];
            //[self.view sendSubviewToBack:light];
            escape = YES;
        }
    }

    [self performSelector:@selector(lightRandomLight) withObject:nil afterDelay:0.2];
}

- (void)switchOffRandomLight
{
     NSLog(@"switchOffRandomLight");
    int rand = arc4random() % [lit count];
    UIView *light = [lit objectAtIndex:rand];
    [lit removeObject:light];
    [light removeFromSuperview];

    [self performSelector:@selector(switchOffRandomLight) withObject:nil afterDelay:0.5];
}
4

3 に答える 3

1

すべてのライトが点灯すると、whileループが継続的に実行され、点灯していない乱数を取得しようとしているようです。これがメインスレッドをブロックするものです。

必要なのは、メソッドの開始時にすべてのライトが点灯しているかどうかを確認し、点灯していない場合は続行することです。

lightRandomLightメソッドの下部で、

[self performSelector:@selector(lightRandomLight) withObject:nil afterDelay:0.2];

if ([lit count] != [rects count]) {
    [self performSelector:@selector(lightRandomLight) withObject:nil afterDelay:0.2];
} else {
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}

すべてのライトが点灯すると停止します。

于 2012-09-18T17:11:49.553 に答える
0

メインスレッドをブロックしています-lightRandomLight終了すると、0.2秒の遅延で自分自身を呼び出します。したがって、メインスレッドがユーザーの操作に応答することはありません。UIViewが提供するアニメーションAPIを見てください。サブビューを追加および削除して「アニメーション化」するのではなく、ビューのアルファステータスまたは背景色を設定したり、遅延を設定したり、ループを設定したりできます。

于 2012-09-18T14:23:09.493 に答える
0

私の推測では、それwhile (!escape) {}は決して完了しません(したがって、エスケープは決してYESではありません)。

于 2012-09-18T14:24:09.880 に答える