右手あげて、左手あげて、両手上げてと動くように作ってみる
(XcodeのiOS6 Simulatorで試しています。)
ポイント
・腕の位置は角度で指定。UIViewのdrawRectで指定の角に描画
・右手、左手、両手のボタンを作る
・手の位置座標をUILabelに表示しておく
サンプルコード
——————————–
StickPerson.h
#import <Foundation/Foundation.h>
@interface StickPerson : UIView
@property (nonatomic, assign) CGPoint leftHand;
@property (nonatomic, assign) CGPoint rightHand;
@property (nonatomic, assign) float leftHandAngle;
@property (nonatomic, assign) float rightHandAngle;
@end
——————————–
StickPerson.m
#import “StickPerson.h”
@implementation StickPerson
@synthesize leftHand, rightHand, leftHandAngle, rightHandAngle;
– (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
// パーツの基本となる長さ
float size = self.bounds.size.width * 0.1;
// 塗りつぶしの色をセット
[[UIColor grayColor] setFill];
// 線の設定(手足は線で書く)
[[UIColor grayColor] set];
CGContextSetLineWidth(context, size);
CGContextSetLineCap(context, kCGLineCapRound);
// 頭
float headX = 5 * size; // center of view
float headY = 2 * size;
float headSize = size;
CGContextBeginPath(context);
CGContextAddArc(context, headX, headY, headSize, 0, 2*M_PI, YES);
CGContextFillPath(context);
// 胴体
CGRect bodyRect = CGRectMake(4 * size, headY + size, 2 * size, 3 * size);
CGContextBeginPath(context);
CGContextAddRect(context, bodyRect);
CGContextFillPath(context);
// 左手
CGPoint leftShoulder = CGPointMake(4*size, bodyRect.origin.y + size * 0.5);
CGContextBeginPath(context);
CGContextMoveToPoint(context, leftShoulder.x, leftShoulder.y);
float lx = leftShoulder.x – 2 * size *cos(leftHandAngle);
float ly = leftShoulder.y – 2 * size *sin(leftHandAngle);
leftHand = CGPointMake(lx, ly);
CGContextAddLineToPoint(context, leftHand.x, leftHand.y);
CGContextDrawPath(context, kCGPathStroke);
// 右手
CGPoint rightShoulder = CGPointMake(6*size, bodyRect.origin.y + size * 0.5);
CGContextBeginPath(context);
CGContextMoveToPoint(context, rightShoulder.x, rightShoulder.y);
float rx = rightShoulder.x + 2 * size *cos(rightHandAngle);
float ry = rightShoulder.y – 2 * size *sin(rightHandAngle);
rightHand = CGPointMake(rx, ry);
CGContextAddLineToPoint(context, rightHand.x, rightHand.y);
CGContextDrawPath(context, kCGPathStroke);
// 左足
CGPoint leftLegRoot = CGPointMake(4.5*size, size * 6);
CGPoint leftFoot = CGPointMake(4*size, size * 9);
CGContextBeginPath(context);
CGContextMoveToPoint(context, leftLegRoot.x, leftLegRoot.y);
CGContextAddLineToPoint(context, leftFoot.x, leftFoot.y);
CGContextDrawPath(context, kCGPathStroke);
// 右足
CGPoint rightLegRoot = CGPointMake(5.5*size, size * 6);
CGPoint rightFoot = CGPointMake(6*size, size * 9);
CGContextBeginPath(context);
CGContextMoveToPoint(context, rightLegRoot.x, rightLegRoot.y);
CGContextAddLineToPoint(context, rightFoot.x, rightFoot.y);
CGContextDrawPath(context, kCGPathStroke);
// 糸を通す穴
// 白
[[UIColor whiteColor] setFill];
CGContextBeginPath(context);
CGContextAddArc(context, leftHand.x, leftHand.y, size * 0.2, 0, 2*M_PI, YES);
CGContextFillPath(context);
CGContextBeginPath(context);
CGContextAddArc(context, rightHand.x, rightHand.y, size * 0.2, 0, 2*M_PI, YES);
CGContextFillPath(context);
}
@end
——————————–
ViewController.m
#import “ViewController.h”
#import “StickPerson.h”
#import <QuartzCore/QuartzCore.h>
typedef enum {
PersonStatusFree = 0,
PersonStatusHandsUp,
PersonStatusRightHandUp,
PersonStatusLeftHandUp,
} PersonStatus;
@interface ViewController () {
StickPerson *stickPerson;
CADisplayLink *timer;
PersonStatus status;
UILabel *leftData;
UILabel *rightData;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
stickPerson = [[StickPerson alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
stickPerson.center = CGPointMake(160, 300);
stickPerson.backgroundColor = [UIColor clearColor];
[self.view addSubview:stickPerson];
[self createButtons];
[self createDataBox];
[self start];
}
– (void)createDataBox
{
leftData = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
leftData.center = CGPointMake(50, 100);
leftData.backgroundColor = [UIColor blackColor];
leftData.text = [self leftHandData];
leftData.textColor = [UIColor whiteColor];
leftData.textAlignment = 1; // center
[self.view addSubview:leftData];
rightData = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
rightData.center = CGPointMake(270, 100);
rightData.backgroundColor = [UIColor blackColor];
rightData.text = [self rightHandData];
rightData.textColor = [UIColor whiteColor];
rightData.textAlignment = 1; // center
[self.view addSubview:rightData];
}
– (NSString*)rightHandData
{
return [NSString stringWithFormat:@”x:%2.f y:%2.f”, stickPerson.rightHand.x, stickPerson.rightHand.y];
}
– (NSString*)leftHandData
{
return [NSString stringWithFormat:@”x:%2.f y:%2.f”, stickPerson.leftHand.x, stickPerson.leftHand.y];
}
– (void)createButtons
{
// 両手を上げるボタン
StickPerson *up = [[StickPerson alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
up.leftHandAngle = M_PI * 0.4;
up.rightHandAngle = M_PI * 0.4;
up.center = CGPointMake(50, 400);
up.backgroundColor = [UIColor blackColor];
up.tag = PersonStatusHandsUp;
[self.view addSubview:up];
UITapGestureRecognizer *upTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeState:)];
[up addGestureRecognizer:upTap];
// 右手を上げるボタン
StickPerson *rup = [[StickPerson alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
rup.leftHandAngle = – M_PI * 0.4;
rup.rightHandAngle = M_PI * 0.4;
rup.center = CGPointMake(120, 400);
rup.backgroundColor = [UIColor blackColor];
rup.tag = PersonStatusRightHandUp;
[self.view addSubview:rup];
UITapGestureRecognizer *rTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeState:)];
[rup addGestureRecognizer:rTap];
// 左手を上げるボタン
StickPerson *lup = [[StickPerson alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
lup.leftHandAngle = M_PI * 0.4;
lup.rightHandAngle = – M_PI * 0.4;
lup.center = CGPointMake(190, 400);
lup.backgroundColor = [UIColor blackColor];
lup.tag = PersonStatusLeftHandUp;
[self.view addSubview:lup];
UITapGestureRecognizer *lTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeState:)];
[lup addGestureRecognizer:lTap];
// 両手を下げる
StickPerson *down = [[StickPerson alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
down.leftHandAngle = – M_PI * 0.4;
down.rightHandAngle = – M_PI * 0.4;
down.center = CGPointMake(260, 400);
down.backgroundColor = [UIColor blackColor];
down.tag = PersonStatusFree;
[self.view addSubview:down];
UITapGestureRecognizer *dTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeState:)];
[down addGestureRecognizer:dTap];
}
– (void)start
{
timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisp:)];
[timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
– (void)changeState:(UIGestureRecognizer*)gr
{
status = gr.view.tag;
}
– (void)updateDisp:(CADisplayLink*)sender
{
if (status == PersonStatusHandsUp) {
if (stickPerson.rightHandAngle <= M_PI * 0.4) {
stickPerson.rightHandAngle += M_PI * 0.01;
}
if (stickPerson.leftHandAngle <= M_PI * 0.4) {
stickPerson.leftHandAngle += M_PI * 0.01;
}
[stickPerson setNeedsDisplay];
}
if (status == PersonStatusRightHandUp) {
if (stickPerson.rightHandAngle <= M_PI * 0.4) {
stickPerson.rightHandAngle += M_PI * 0.01;
}
if (stickPerson.leftHandAngle >= – M_PI * 0.4) {
stickPerson.leftHandAngle -= M_PI * 0.01;
}
[stickPerson setNeedsDisplay];
}
if (status == PersonStatusLeftHandUp) {
if (stickPerson.rightHandAngle >= –M_PI * 0.4) {
stickPerson.rightHandAngle -= M_PI * 0.01;
}
if (stickPerson.leftHandAngle <= M_PI * 0.4) {
stickPerson.leftHandAngle += M_PI * 0.01;
}
[stickPerson setNeedsDisplay];
}
if (status == PersonStatusFree) {
if (stickPerson.rightHandAngle >= –M_PI * 0.4) {
stickPerson.rightHandAngle -= M_PI * 0.01;
}
if (stickPerson.leftHandAngle >= – M_PI * 0.4) {
stickPerson.leftHandAngle -= M_PI * 0.01;
}
[stickPerson setNeedsDisplay];
}
//update data box
leftData.text = [self leftHandData];
rightData.text = [self rightHandData];
[self updateWire];
}
#define WireView 111
– (void)updateWire
{
//clean
for (UIView *v in self.view.subviews) {
if (v.tag == WireView) {
[v removeFromSuperview];
}
}
// 左のワイヤー
CGPoint leftHandGlobal = [self.view convertPoint:stickPerson.leftHand fromView:stickPerson];
CGPoint lConnector = CGPointMake(leftData.center.x, leftHandGlobal.y);
UIView *lineL1 = [[UIView alloc] initWithFrame:CGRectMake(leftData.center.x, leftData.center.y, 1, lConnector.y – leftData.center.y)];
lineL1.backgroundColor = [UIColor blackColor];
lineL1.tag = WireView;
[self.view addSubview:lineL1];
UIView *lineL2 = [[UIView alloc] initWithFrame:CGRectMake(lConnector.x, lConnector.y, leftHandGlobal.x – lConnector.x, 1)];
lineL2.backgroundColor = [UIColor blackColor];
lineL2.tag = WireView;
[self.view addSubview:lineL2];
UIView *lCon = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
lCon.backgroundColor = [UIColor lightGrayColor];
lCon.center = lConnector;
lCon.tag = WireView;
[self.view addSubview:lCon];
// 右のワイヤー
CGPoint rHandGlobal = [self.view convertPoint:stickPerson.rightHand fromView:stickPerson];
CGPoint rConnector = CGPointMake(rightData.center.x, rHandGlobal.y);
UIView *lineR1 = [[UIView alloc] initWithFrame:CGRectMake(rightData.center.x, rightData.center.y, 1, rConnector.y – rightData.center.y)];
lineR1.backgroundColor = [UIColor blackColor];
lineR1.tag = WireView;
[self.view addSubview:lineR1];
UIView *lineR2 = [[UIView alloc] initWithFrame:CGRectMake(rConnector.x, rConnector.y, rHandGlobal.x – rConnector.x, 1)];
lineR2.backgroundColor = [UIColor blackColor];
lineR2.tag = WireView;
[self.view addSubview:lineR2];
UIView *rCon = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
rCon.backgroundColor = [UIColor lightGrayColor];
rCon.center = rConnector;
rCon.tag = WireView;
[self.view addSubview:rCon];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end