右手あげて、左手あげて、両手上げてと動くように作ってみる

(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.x2 * size *cos(leftHandAngle);

    float ly = leftShoulder.y2 * 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.y2 * 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.yleftData.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.yrightData.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