飛行機のレーダーみたいな、くるくる回りならがら隠れた点を発見するおもちゃをiPhoneアプリとして作ってみる。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
ポイント
くるくるする部分が回るときに、残像としてCALayerを残すことで、レーダーっぽさを出してみました。ランダムに配置した点は、くるくるする部分のpresentationLayerのhitTestを使って、接触したら点滅するようにしています。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()
{
UIView *hand;
NSMutableArray *targets;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [self color:0];
[self createGridSheet];
[self createContourLine];
[self createHand];
[self createTargets];
[self start];
}
– (void)createContourLine
{
float radius[] = {50, 100, 150};
for (int i=0; i<3; i++) {
float size = radius[i] * 2.0;
UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size, size)];
line.backgroundColor = [UIColor clearColor];
line.layer.borderColor = [self color:3].CGColor;
line.layer.borderWidth = 2;
line.center = CGPointMake(160, 160);
line.layer.cornerRadius = radius[i];
[self.view addSubview:line];
}
}
– (void)createHand
{
hand = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 4)];
hand.backgroundColor = [self color:3];
[self.view addSubview:hand];
hand.layer.anchorPoint = CGPointMake(0, 0.5);
hand.layer.position = CGPointMake(160, 160);
}
– (void)createTargets
{
targets = [[NSMutableArray alloc] init];
for (int i = 0; i < 20; i++) {
float x = arc4random() % 300 + 10;
float y = arc4random() % 300 + 10;
UIView *t = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
t.layer.cornerRadius = 5.0;
t.center = CGPointMake(x, y);
t.backgroundColor = [self color:3];
t.alpha = 0.0;
[self.view addSubview:t];
[targets addObject:t];
}
}
– (void)start
{
[NSTimer scheduledTimerWithTimeInterval:1.5/60.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
}
– (void)tick:(NSTimer*)sender
{
hand.transform = CGAffineTransformRotate(hand.transform, M_PI * 0.01);
float angle = [[hand.layer valueForKeyPath:@”transform.rotation.z”] floatValue];
CALayer *line = [CALayer layer];
line.frame = CGRectMake(0, 0, 150, 3);
line.anchorPoint = CGPointMake(0, 0.5);
line.position = CGPointMake(160, 160);
line.transform = CATransform3DMakeRotation(angle, 0, 0, 1);
line.backgroundColor = [self color:3].CGColor;
line.opacity = 0;
[self.view.layer addSublayer:line];
for (int i=0; i<[targets count]; i++) {
UIView *t = [targets objectAtIndex:i];
if ([hand.layer.presentationLayer hitTest:t.center]) {
t.alpha = 0.95;
[UIView animateWithDuration:1.5 animations:^{
t.alpha = 0.0;
}];
}
}
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@”opacity”];
fade.fromValue = @1.0;
fade.toValue = @0;
fade.duration = 0.5;
[line addAnimation:fade forKey:nil];
[line performSelector:@selector(removeFromSuperlayer) withObject:nil afterDelay:0.5];
}
– (void)createGridSheet
{
UIBezierPath *path = [UIBezierPath bezierPath];
float size = 32;
for (int i=0; i<320/size; i++) {
[path moveToPoint:CGPointMake(i * size, 0)];
[path addLineToPoint:CGPointMake(i * size, 568)];
}
for (int i=0; i<568/size; i++) {
[path moveToPoint:CGPointMake(0, i*size)];
[path addLineToPoint:CGPointMake(320, i*size)];
}
CAShapeLayer *sl = [[CAShapeLayer alloc] init];
sl.strokeColor = [self color:1].CGColor;
sl.lineWidth = 1;
sl.path = path.CGPath;
[self.view.layer addSublayer:sl];
}
#define UIColorHex(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
– (UIColor*)color:(int)i
{
switch (i) {
case 0:
return UIColorHex(0x122B1C);
case 1:
return UIColorHex(0x467339);
case 2:
return UIColorHex(0x78AB46);
case 3:
return UIColorHex(0xB5ED63);
case 4:
return UIColorHex(0xF2F7CD);
default:
break;
}
return nil;
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end