点を縦横に並べた大きな円盤を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(568 – 100, 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.0 – 100, 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