まずは、赤、青、黄色などランダムに出る明るい色で
下地を作ります。スタートボタンを押すと、
ひっかきタイムの始まりです。
適当に線を引くだけで芸術家気分に!
という感じでiPhoneアプリのサンプル描いてみました。

ポイント
scratchBoardという名前でUIViewを作っておいて、
Layerをカラフルに塗込んでいきます。
引っ掻きモードになったら、別のレイヤーをmask用に用意しています。
カラフルなレイヤーにこの引っ掻き用レイヤーをmaskとしてかぶせることで、
スクラッチしたところが見えるようにしてみました。

環境
今回つくったiPhoneアプリサンプルは、
XcodeのiOS6 iPhone Simulatorで動かしています。


サンプルコード


#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

#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]

typedef enum {

    DrawColor,

    Scratch,

} DrawState;

@interface ViewController () {

    UIBezierPath *scratchPath;

    CAShapeLayer *scratchLayer;

    

    UIBezierPath *drawPath;

    CAShapeLayer *drawLayer;

    

    UIView *scratchboard;

    DrawState state;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor blackColor];

    

    [self createScratchboard];

    

    [self createUI];

}

– (void)createUI

{

    UILabel *btn = [[UILabel alloc] initWithFrame:CGRectMake(110, 0, 100, 40)];

    btn.text = @”start”;

    btn.font = [UIFont boldSystemFontOfSize:30];

    btn.textAlignment = 1;

    btn.layer.borderWidth = 3;

    btn.layer.cornerRadius = 20;

    btn.userInteractionEnabled = YES;

    btn.backgroundColor = [UIColor lightGrayColor];

    [self.view addSubview:btn];

    

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

    [btn addGestureRecognizer:tap];

}

– (void)start:(UITapGestureRecognizer*)gr

{

    [UIView animateWithDuration:0.2 animations:^{

        gr.view.transform = CGAffineTransformMakeTranslation(0, –50);

    } completion:^(BOOL finished) {

        UILabel *l = (UILabel*)gr.view;

        if ([l.text isEqual:@”start”]) {

            l.text = @”reset”;

            state = Scratch;

        } else {

            l.text = @”start”;

            state = DrawColor;

            [scratchboard removeFromSuperview];

            [self createScratchboard];

            [self.view insertSubview:gr.view aboveSubview:scratchboard];

            scratchPath = nil;

        }

        [UIView animateWithDuration:0.2 animations:^{

            gr.view.transform = CGAffineTransformIdentity;

        }];

    }];

}

– (void)createScratchboard

{

    scratchboard = [[UIView alloc] initWithFrame:self.view.bounds];

    scratchboard.backgroundColor = [UIColor whiteColor];

    [self.view addSubview:scratchboard];

}

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

{

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

    if (state == Scratch) {

        if (!scratchPath) {

            scratchPath = [[UIBezierPath alloc] init];

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

            scratchLayer.fillColor = [UIColor clearColor].CGColor;

            scratchLayer.strokeColor = [UIColor blackColor].CGColor;

            scratchLayer.lineWidth = 10.0;

        }

        [scratchPath moveToPoint:p];

    } else {

        // colorful

        NSArray *colors = [NSArray arrayWithObjects:UIColorHex(0xF60000),UIColorHex(0x09AFCC),UIColorHex(0x2FFB03),UIColorHex(0xFFF700),UIColorHex(0xFF8800), nil];

        UIColor *randomColor = [colors objectAtIndex:arc4random() % 5];

        

        drawPath = [[UIBezierPath alloc] init];

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

        drawLayer.fillColor = [UIColor clearColor].CGColor;

        drawLayer.strokeColor = randomColor.CGColor;

        drawLayer.lineWidth = 30.0;

        [scratchboard.layer addSublayer:drawLayer];

        [drawPath moveToPoint:p];

    }

}

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

{

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

    if (state == Scratch) {

        [scratchPath addLineToPoint:p];

        scratchLayer.path = scratchPath.CGPath;

        scratchboard.layer.mask = scratchLayer;

    } else {

        [drawPath addLineToPoint:p];

        drawLayer.path = drawPath.CGPath;

    }

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end