【问题标题】:lights animation in objective-cObjective-C中的灯光动画
【发布时间】:2012-09-06 01:46:55
【问题描述】:

我正在尝试在 Objective-c 中实现一个动画,其中我有一个纽约天际线插图作为附加图像。要求是实现城市灯光动画,其中天际线建筑物中的灯光(方形和矩形框)依次点亮......以吸引人的动画方式。实现这一点的一种方法是使用一组连续图像(UIImageView.animationImages = 图像数组),但我相信可能有更好、更有效的方法来实现这一点。如果有人能指出正确的方向,我将不胜感激。

【问题讨论】:

    标签: objective-c ios


    【解决方案1】:
    [UIView animateWithDuration:1 delay:0 options:0 animations:^{
        light1.alpha = 1;
    } completion:nil];
    
    [UIView animateWithDuration:1 delay:0.5 options:0 animations:^{
        light2.alpha = 1;
    } completion:nil];
    
    [UIView animateWithDuration:1 delay:1 options:0 animations:^{
        light3.alpha = 1;
    } completion:nil];
    
    [UIView animateWithDuration:1 delay:1.5 options:0 animations:^{
        light4.alpha = 1;
    } completion:nil];
    

    在创建灯光视图时将其 alpha 设置为 0,然后在 -viewDidAppear 中运行它也许... (这是假设每个灯都是一个单独的UIView...)

    如果您有很多视图,您可以这样做来为每个视图的 alpha 值设置动画:

    float n = 0; 
    for (UIView* v in self.view.subviews) { 
        if (v.alpha < 0.5) { 
            [UIView animateWithDuration:1 delay:n options:0 animations:^{ 
                v.alpha = 1; 
            } completion:nil]; 
            n += 0.5;
        } 
    }
    

    【讨论】:

    • 感谢您的回答。总共有很多灯(结合所有建筑物),例如 - 在左起第二个建筑物中,我有 15 排灯。你认为我应该为每栋建筑的每一排灯都有一个 UIView 吗?
    • 这是很多视图,可能会导致一些缓慢...但是如果您想尝试通过迭代子视图来简化动画代码:float n = 0; for (UIView* v in self.view.subviews) { if (v.alpha &lt; 0.5) { [UIView animateWithDuration:1 delay:n options:0 animations:^{ v.alpha = 1; completion:nil]; n += 0.5 } }
    • 谢谢。总结一下这个方法,对于左起第二个建筑(有 15 排灯),我应该首先以编程方式添加 60 个(15 X 4)个 alpha = 0 的 UIView,然后在循环中将它们的 alpha 设置为 1。对所有其他建筑物做同样的事情吗?我理解正确吗?
    【解决方案2】:

    为什么不拥有一个 CGRect 数组,其中包含每个灯光的坐标。 然后您可以简单地在矩形周围移动 1 个 UIView,或者如果一次照明超过 1 个,则移动几个 UIView。

    编辑------- 只是一些简单的代码放在一起。

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor blackColor];
        rects = [[NSMutableArray alloc] init];
        lit = [[NSMutableArray alloc] init];
    
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(20, 20, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(60, 20, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(100, 20, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(140, 20, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(180, 20, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(220, 20, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(260, 20, 20, 20)]];
    
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(20, 60, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(60, 60, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(100, 60, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(140, 60, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(180, 60, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(220, 60, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(260, 60, 20, 20)]];
    
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(20, 100, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(60, 100, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(100, 100, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(140, 100, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(180, 100, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(220, 100, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(260, 100, 20, 20)]];
    
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(20, 140, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(60, 140, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(100, 140, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(140, 140, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(180, 140, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(220, 140, 20, 20)]];
        [rects addObject:[NSValue valueWithCGRect:CGRectMake(260, 140, 20, 20)]];
    }
    
    - (void)viewDidAppear:(BOOL)animated
    {
        [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 yellowColor];
                [lit addObject:light];
                [self.view addSubview:light];
                escape = YES;
            }
        }
    
        [self performSelector:@selector(lightRandomLight) withObject:nil afterDelay:0.2];
    }
    
    - (void)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];
    }
    

    【讨论】:

    • 谢谢达伦。这听起来是个不错的方法。最初,所有灯都关闭,然后依次点亮,但在某些时候,所有建筑物的所有灯都会亮起。这种方法在这种情况下仍然有效吗?你能提供一个伪代码吗?我将不胜感激。
    • 谢谢达伦。我将尝试这种方法,并让你知道它是如何进行的。感谢您抽出时间并提供伪代码以供我理解。
    • 我知道你可能不会使用这个,但是我很无聊并且很喜欢这个任务。我在上面编辑了我的代码。把它放在一个 ViewController 中,观察所有的灯闪烁,直到它们全部亮起。
    • Darren,我测试了这个解决方案,效果很好。只是想知道我是否想按顺序点亮灯(第 1 行比第 2 行比第 3 行等),是否可以分配某种标签并通过标签点亮它们?
    • 您可以按照您希望它们点亮的顺序将 CGrects 放入数组中,然后不使用随机数,而是从头到尾遍历数组。
    【解决方案3】:

    这可能有点工作,但我可能会尝试将窗口颜色设置为 alpha,然后“翻转”图像后面的灯光。

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      相关资源
      最近更新 更多