iPhone色と駐車

点線と同じ色のところに車を駐車していく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.y60);

        }

    }];

    

    [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