2

我试图通过拥有一个 CGRect 数组和每个灯光的坐标来实现城市灯光动画。然后围绕这些 CGRects 创建 UIViews。这个逻辑(感谢Darren帮助这个逻辑)工作正常,但是在动画完成后,屏幕上的所有其他元素(UIButtons、Sliders、其他 UIImageViews 等)都变得无法访问。甚至我的滑动手势也没有响应。在动画之前和期间,所有元素都响应良好,但是一旦动画完成,它们都变得不可访问。我还尝试[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——不是通过添加和删除子视图来“动画化”,而是可以设置视图的 alpha 状态或背景颜色,还可以设置延迟和设置循环。

于 2012-09-18T14:23:09.493 回答
0

我的猜测是这while (!escape) {}永远不会完成(所以逃避永远不会是)。

于 2012-09-18T14:24:09.880 回答