Reputation: 833
I am trying to implement a animation in objective-c where I have a NY skyline illustration as attached image. Requirement is to implement city lights animations where lights (square and rectangle boxes) in skyline buildings lit sequentially... in an appealing animated way. One of the ways to achieve this is using a set of sequential images (UIImageView.animationImages = array of images) but I am sure there might be better and more efficient ways to achieve this. I would greatly appreciate if someone can point me in the right direction.
Upvotes: 2
Views: 839
Reputation: 10398
Why not have an array of CGRect's with the coords of each light. Then you can simply move 1 UIView around the rects, or if lighting more than 1 at a time then move a couple of UIViews around.
EDIT------- Just some quick code thrown together.
- (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];
}
Upvotes: 1
Reputation: 4436
This might be a bit of work, but I might try to set the window color to alpha, and then "flip on" the lights behind the image.
Upvotes: 0
Reputation: 4140
[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];
Set the light views alpha to 0 when you create them, and run this in -viewDidAppear
maybe...
(This is assuming each light is a separate UIView
...)
If you have a lot of views you could do this to animate each one's alpha value:
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;
}
}
Upvotes: 2