iPhone smileyアプリ

点を縦横に並べた大きな円盤を2つ、半円を縦横に並べた大きな円盤を1つ用意します。この3つの円を重ねると、スマイルが完成します。というとても単純なiPhoneアプリを作っていきたいと思います。


動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。

ポイント
点の円には、5×5で計25個の点をUIBezierPathとCAShapeLayerをつかってsubLayerに追加しています。円のViewのmaskToBoundsをYESにしているので、円の外になる点は表示されません。口になる半円も同じ要領で描いています。大きな円にはUIPanGestureRecognizerを設定して、指で動かせるようにしています。動かすViewが大きいので、最初にタッチした場所と指がずれないように、BeganのStatusの際に、anchorPointをタッチした座標にずらしています。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

#define UIColorHex(rgbValue, a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:a]

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = [self color:0];

    

    UIView *eyeA = [self createEyes];

    eyeA.center = CGPointMake(100, 100);

    eyeA.backgroundColor = [self color:1];

    

    UIView *eyeB = [self createEyes];

    eyeB.center = CGPointMake(568100, 100);

    eyeB.backgroundColor = [self color:3];

    

    [self createMouth];

}

– (UIView*)createEyes

{

    UIView *eyeArea = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];

    eyeArea.layer.cornerRadius = 100;

    eyeArea.layer.masksToBounds = YES;

    

    // eyes

    UIBezierPath *path = [UIBezierPath bezierPath];

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

        float x = (i % 5) * 40;

        float y = (i / 5) * 40;

        [path addArcWithCenter:CGPointMake(x + 15, y + 20) radius:3 startAngle:0 endAngle:2*M_PI clockwise:YES];

        [path closePath];

    }

    CAShapeLayer *sl = [[CAShapeLayer alloc] init];

    sl.fillColor = [self color:2].CGColor;

    sl.path = path.CGPath;

    

    [eyeArea.layer addSublayer:sl];

    [self.view addSubview:eyeArea];

    

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];

    [eyeArea addGestureRecognizer:pan];

    

    return eyeArea;

}

– (void)createMouth

{

    UIView *mouth = [[UIView alloc] initWithFrame:CGRectMake(568 / 2.0100, 100, 200, 200)];

    mouth.backgroundColor = [self color:4];

    mouth.layer.cornerRadius = 100;

    mouth.layer.masksToBounds = YES;

    

    UIBezierPath *path = [UIBezierPath bezierPath];

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

        float x = (i % 5) * 40 + 20;

        float y = (i / 5) * 40 + 20;

        

        [path appendPath:[UIBezierPath bezierPathWithArcCenter:CGPointMake(x, y) radius:10 startAngle:M_PI endAngle:0 clockwise:NO]];

    }

    CAShapeLayer *sl = [[CAShapeLayer alloc] init];

    sl.fillColor = [UIColor clearColor].CGColor;

    sl.strokeColor = [self color:2].CGColor;

    sl.lineWidth = 2;

    sl.path = path.CGPath;

    [mouth.layer addSublayer:sl];

    

    [self.view addSubview:mouth];

    

    

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];

    [mouth addGestureRecognizer:pan];

}

– (void)move:(UIPanGestureRecognizer*)gr

{

    

    if (gr.state == UIGestureRecognizerStateBegan)

    {

        CGPoint p = [gr locationInView:gr.view];

        gr.view.layer.anchorPoint = CGPointMake(p.x/gr.view.frame.size.width, p.y/gr.view.frame.size.height);

        gr.view.layer.position = [gr locationInView:self.view];

    } else if (gr.state == UIGestureRecognizerStateChanged) {

        gr.view.layer.position = [gr locationInView:self.view];

    }

}

– (UIColor*)color:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0xE9F2D5, 1.0);

        case 1:

            return UIColorHex(0xFE7026, 0.2);

        case 2:

            return UIColorHex(0x53A68E, 1.0);

        case 3:

            return UIColorHex(0xE71382, 0.2);

        case 4:

            return UIColorHex(0xB8B100, 0.2);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end