点線と同じ色のところに車を駐車していくiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@interface ViewController ()
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
[self createPark];
[self createRoadSign];
for (int i=0; i<5; i++) {
[self updateCarLine];
}
[self createCars];
}
– (void)createPark
{
UIView *park = [[UIView alloc] initWithFrame:CGRectMake(-40, –40, 280, 400)];
park.backgroundColor = [UIColor colorWithWhite:0.2 alpha:1];
park.layer.cornerRadius = 20;
[self.view addSubview:park];
}
– (void)createLine
{
NSMutableArray *color = [@[[UIColor redColor], [UIColor greenColor], [UIColor blueColor]] mutableCopy];
for (int i=0; i<3; i++) {
float x = i * 60 + 40;
float y = 300;
CAShapeLayer *car = [self createCar];
car.name = @”carline”;
car.position = CGPointMake(x, y);
UIColor *c = color[arc4random() % color.count];
[color removeObject:c];
car.strokeColor = c.CGColor;
car.fillColor = [UIColor clearColor].CGColor;
car.lineWidth = 2;
car.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
car.lineDashPattern = @[@(1),@(1)];
[self.view.layer addSublayer:car];
}
}
– (void)createCars
{
NSMutableArray *color = [@[[UIColor redColor], [UIColor greenColor], [UIColor blueColor]] mutableCopy];
for (int i=0; i<3; i++) {
float x = 80;
float y = CGRectGetMaxY(self.view.bounds) – 40 * i – 20;
CAShapeLayer *car = [self createCar];
car.name = @”car”;
car.position = CGPointMake(x, y);
car.fillColor = [color[i] CGColor];
[self.view.layer addSublayer:car];
}
}
– (CAShapeLayer *)createCar
{
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 40, 20)];
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(2, 5, 10, 5)]];
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(27, 5, 10, 5)]];
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(2, 30, 10, 5)]];
[path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(27, 30, 10, 5)]];
CAShapeLayer *l = [CAShapeLayer layer];
l.frame = CGRectMake(0, 0, 40, 40);
l.path = path.CGPath;
return l;
}
– (void)createRoadSign
{
UILabel *sign1 = [[UILabel alloc] init];
sign1.text = @”→”;
sign1.font = [UIFont boldSystemFontOfSize:60];
sign1.textColor = [UIColor whiteColor];
[sign1 sizeToFit];
sign1.center = CGPointMake(200, 420);
[self.view addSubview:sign1];
UILabel *sign2 = [[UILabel alloc] init];
sign2.text = @”↑”;
sign2.font = [UIFont boldSystemFontOfSize:60];
sign2.textColor = [UIColor whiteColor];
[sign2 sizeToFit];
sign2.center = CGPointMake(280, 240);
[self.view addSubview:sign2];
UILabel *sign3 = [[UILabel alloc] init];
sign3.text = @”←”;
sign3.font = [UIFont boldSystemFontOfSize:60];
sign3.textColor = [UIColor whiteColor];
[sign3 sizeToFit];
sign3.center = CGPointMake(240, 60);
[self.view addSubview:sign3];
}
– (void)updateCarLine
{
[self.view.layer.sublayers enumerateObjectsUsingBlock:^(CALayer *l, NSUInteger idx, BOOL *stop) {
if ([l.name hasPrefix:@”car”]) {
l.position = CGPointMake(l.position.x, l.position.y – 60);
}
}];
[self createLine];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint p = [[touches anyObject] locationInView:self.view];
[self.view.layer.sublayers enumerateObjectsUsingBlock:^(CAShapeLayer *l, NSUInteger idx, BOOL *stop) {
if (CGRectContainsPoint(l.frame, p) && [l.name isEqual:@”car”]) {
NSPredicate *pred = [NSPredicate predicateWithFormat:@”position.y < %d && name = %@”, 80, @”carline”];
NSArray *topParkArea = [self.view.layer.sublayers filteredArrayUsingPredicate:pred];
__block CGPoint goal;
[topParkArea enumerateObjectsUsingBlock:^(CAShapeLayer *park, NSUInteger idx, BOOL *stop) {
if (CGColorEqualToColor(park.strokeColor, l.fillColor)) {
goal = park.position;
park.name = @””;
}
}];
CATransform3D trans = CATransform3DIdentity;
trans = CATransform3DMakeTranslation(200, 0, 0);
[CATransaction begin]; {
[CATransaction setCompletionBlock:^{
[CATransaction setDisableActions: YES];
l.transform = CATransform3DIdentity;
l.position = goal;
if (topParkArea.count == 1) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[CATransaction setDisableActions: NO];
[self updateCarLine];
[self createCars];
});
}
}];
// A
CABasicAnimation *moveA = [CABasicAnimation animationWithKeyPath:@”transform”];
moveA.beginTime = CACurrentMediaTime();
moveA.duration = 1.0;
moveA.toValue = [NSValue valueWithCATransform3D:trans];
moveA.fillMode = kCAFillModeForwards;
[l addAnimation:moveA forKey:nil];
// B
CABasicAnimation *moveB = [CABasicAnimation animationWithKeyPath:@”transform”];
moveB.duration = 0.5;
moveB.beginTime = CACurrentMediaTime() + 1.0;
moveB.fromValue = [NSValue valueWithCATransform3D:trans];
trans = CATransform3DRotate(trans, –M_PI/2.0, 0, 0, 1);
moveB.toValue = [NSValue valueWithCATransform3D:trans];
[l addAnimation:moveB forKey:nil];
// C
CABasicAnimation *moveC = [CABasicAnimation animationWithKeyPath:@”transform”];
moveC.duration = 1.0;
moveC.beginTime = CACurrentMediaTime() + 1.5;
moveC.fromValue = [NSValue valueWithCATransform3D:trans];
float dy = l.position.y – goal.y;
trans = CATransform3DTranslate(trans, dy, 0, 0);
moveC.toValue = [NSValue valueWithCATransform3D:trans];
[l addAnimation:moveC forKey:nil];
// D
CABasicAnimation *moveD = [CABasicAnimation animationWithKeyPath:@”transform”];
moveD.duration = 0.5;
moveD.beginTime = CACurrentMediaTime() + 2.5;
moveD.fromValue = [NSValue valueWithCATransform3D:trans];
trans = CATransform3DRotate(trans, –M_PI/2.0, 0, 0, 1);
moveD.toValue = [NSValue valueWithCATransform3D:trans];
[l addAnimation:moveD forKey:nil];
// E
CABasicAnimation *moveE = [CABasicAnimation animationWithKeyPath:@”transform”];
moveE.duration = 1.0;
moveE.beginTime = CACurrentMediaTime() + 3.0;
moveE.fromValue = [NSValue valueWithCATransform3D:trans];
float dx = 280 – goal.x;
trans = CATransform3DTranslate(trans, dx, 0, 0);
moveE.toValue = [NSValue valueWithCATransform3D:trans];
moveE.removedOnCompletion = NO;
[l addAnimation:moveE forKey:nil];
} [CATransaction commit];
}
}];
}
@end