点つなぎiPhoneアプリのサンプルを書いてみた。
8個の点を表示して、1から8まで順番に繋ぐと
丸になるようにしています。
光る点の順番を先に準備しておけば色んな形が
かけるようになります。(※サンプルは、丸のみです。)

環境
XcodeのiOS6 iPhone Simulatorで動かしています。

ポイント
touchBeginでCAShapeLayer, UIBezierPathを準備、
touchMoveでパスのaddLineで線を繋いでいく。



サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    CGPoint dot[8];

    UIBezierPath *path;

    CAShapeLayer *slayer;

    UILabel *label;

    BOOL start;

    int current;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor greenColor];

    

    [self createDot];

    

    [self createUI];

}

– (void)createDot

{

    

    NSMutableArray *colors = [[NSMutableArray alloc] init];

    for (int i=0; i<8; i++) {

        [colors addObject:[UIColor colorWithHue:i*0.125 saturation:1.0 brightness:0.5 alpha:1.0]];

    }

    

    for (int i=0; i<8; i++) {

        float angle = i * M_PI / 4.0;

        float x = 140 * cos(angle) + 160;

        float y = 140 * sin(angle) + 260;

        dot[i] = CGPointMake(x, y);

        

        UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];

        v.center = dot[i];

        v.tag = i + 1;

        v.layer.cornerRadius = 5.0;

        v.backgroundColor = [colors objectAtIndex:i];

        v.layer.borderColor = [UIColor whiteColor].CGColor;

        v.layer.borderWidth = 4.0;

        [self.view addSubview:v];

        

        UILabel *number = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];

        number.text = [NSString stringWithFormat:@”%d”, i+1];

        number.center = CGPointMake(x, y+30);

        number.backgroundColor = [UIColor clearColor];

        number.font = [UIFont fontWithName:@”Noteworthy-Bold” size:20];

        number.textAlignment = 1;

        [self.view addSubview:number];

    }

}

– (void)createUI

{

    UIView *btn = [[UIView alloc] initWithFrame:CGRectMake(110, 10, 100, 50)];

    btn.backgroundColor = [UIColor whiteColor];

    btn.layer.cornerRadius = 25.0;

    btn.layer.masksToBounds = YES;

    [self.view addSubview:btn];

    

    label = [[UILabel alloc] init];

    label.text = @”START”;

    label.backgroundColor = [UIColor clearColor];

    label.font = [UIFont fontWithName:@”Noteworthy-Bold” size:20];

    [label sizeToFit];

    label.center = CGPointMake(50, 25);

    [btn addSubview:label];

    

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];

    [btn addGestureRecognizer:tap];

}

– (void)tap:(UIGestureRecognizer*)gr

{

    UILabel *l = [gr.view.subviews objectAtIndex:0];

    

    [UIView animateWithDuration:0.4 animations:^{

        

        l.transform = CGAffineTransformMakeTranslation(-200, 0);

        

    } completion:^(BOOL finished) {

        

        l.text = @”1″;

        [l sizeToFit];

        

        [UIView animateWithDuration:0.4 animations:^{

            l.transform = CGAffineTransformIdentity;

        } completion:^(BOOL finished) {

            [self flashDot:1];

        }];

    }];

    

    start = YES;

}

– (void)flashDot:(int)i

{

    UIView *v = [self.view viewWithTag:i];

    UIColor *flashColor = [self changeBrightness:1.0 color:v.backgroundColor];

    v.backgroundColor = flashColor;

    

    CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”opacity”];

    a.duration = 0.5;

    a.repeatCount = 100;

    a.fromValue = [NSNumber numberWithFloat:0.2];

    a.toValue = [NSNumber numberWithFloat:1];

    [v.layer addAnimation:a forKey:@”flash”];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    if (!start) {

        return;

    }

    

    path = [[UIBezierPath alloc] init];

    slayer = [[CAShapeLayer alloc] initWithLayer:self.view.layer];

    slayer.lineWidth = 4.0;

    slayer.lineJoin = kCALineJoinBevel;

    slayer.lineCap = kCALineCapRound;

    // 188-143-143

    slayer.strokeColor = [UIColor brownColor].CGColor;

    slayer.fillColor = [UIColor clearColor].CGColor;

    [self.view.layer addSublayer:slayer];

    

    CGPoint p = [[touches anyObject] locationInView:self.view];

    [path moveToPoint:p];

    

    [self checkTouchPoint:p];

    

    self.view.backgroundColor = [UIColor greenColor];

}

– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint p = [[touches anyObject] locationInView:self.view];

    [path addLineToPoint:p];

    slayer.path = path.CGPath;

    

    [self checkTouchPoint:p];

}

– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

    CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”opacity”];

    a.duration = 0.5;

    a.repeatCount = 2;

    a.fromValue = [NSNumber numberWithFloat:0.3];

    a.toValue = [NSNumber numberWithFloat:1];

    [slayer addAnimation:a forKey:@”flash”];

    

    double delayInSeconds = 2.0;

    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);

    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

        [slayer removeAllAnimations];

        [slayer removeFromSuperlayer];

    });

}

– (void)checkTouchPoint:(CGPoint)p

{

    UIView *flash = [self.view viewWithTag:current];

    if (CGRectContainsPoint(flash.frame, p)) {

        [flash.layer removeAllAnimations];

        flash.backgroundColor = [self changeBrightness:0.5 color:flash.backgroundColor];

        

        current = [self getNext];

        if (current > 8) {

            current = 1;

        }

        

        [self flashDot:current];

        

        label.text = [NSString stringWithFormat:@”%d”, current];

        [label sizeToFit];

        label.center = CGPointMake(50, 25);

    }

}

– (int)getNext

{

    return current + 1;

}

– (UIColor*)changeBrightness:(float)new color:(UIColor*)color

{

    CGFloat hue;

    CGFloat saturation;

    CGFloat brightness;

    CGFloat alpha;

    [color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];

    return [UIColor colorWithHue:hue saturation:saturation brightness:new alpha:alpha];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end