iPhoneメガネチェンジ

ボタンをおしてメガネをかけかえて遊ぶiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

@protocol ResizableDynamicItem <UIDynamicItem>

@property (nonatomic, readwrite) CGRect bounds;

@end

@interface APLPositionToBoundsMapping : NSObject <UIDynamicItem>

@property (nonatomic, strong) id<ResizableDynamicItem> target;

– (instancetype)initWithTarget:(id<ResizableDynamicItem>)target;

@end

@implementation APLPositionToBoundsMapping

– (instancetype)initWithTarget:(id<ResizableDynamicItem>)target

{

    self = [super init];

    if (self)

    {

        _target = target;

    }

    return self;

}

– (CGRect)bounds

{

    return self.target.bounds;

}

– (CGPoint)center

{

    return CGPointMake(self.target.bounds.size.width, self.target.bounds.size.height);

}

– (void)setCenter:(CGPoint)center

{

    self.target.bounds = CGRectMake(0, 0, center.x, center.y);

}

– (CGAffineTransform)transform

{

    return self.target.transform;

}

– (void)setTransform:(CGAffineTransform)transform

{

    self.target.transform = transform;

}

@end

@interface ViewController ()

@property (nonatomic, weak) UIView *face;

@property (nonatomic, strong) UIDynamicAnimator *animator;

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

    [self createIcons];

    [self createFace];

}

– (void)createIcons

{

    NSArray *shapes = @[[self createCircleShape]

                        ,[self createTriangleShape]

                        ,[self createRectShape]];

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

        float x = i * 185 + 50;

        float y = 245;

        UIButton *icon = [UIButton buttonWithType:UIButtonTypeCustom];

        icon.tag = i;

        icon.frame = CGRectMake(x, y, 100, 60);

        icon.backgroundColor = [UIColor blackColor];

        icon.layer.cornerRadius = 5;

        icon.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

        icon.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

        [icon.layer addSublayer:shapes[i]];

        [self.view addSubview:icon];

        

        [icon addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];

    }

}

– (CAShapeLayer *)createCircleShape

{

    UIBezierPath *shapeCircle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 30, 30)];

    [shapeCircle appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(60, 10, 30, 30)]];

    [shapeCircle moveToPoint:CGPointMake(0, 25)];

    [shapeCircle addLineToPoint:CGPointMake(10, 25)];

    [shapeCircle moveToPoint:CGPointMake(40, 25)];

    [shapeCircle addLineToPoint:CGPointMake(60, 25)];

    [shapeCircle moveToPoint:CGPointMake(90, 25)];

    [shapeCircle addLineToPoint:CGPointMake(100, 25)];

    CAShapeLayer *l = [CAShapeLayer layer];

    l.path = shapeCircle.CGPath;

    l.fillColor = [UIColor clearColor].CGColor;

    l.strokeColor = [UIColor whiteColor].CGColor;

    l.lineWidth = 3;

    

    return l;

}

– (CAShapeLayer *)createTriangleShape

{

    float s = 40;

    UIBezierPath *shapeTriangle = [UIBezierPath bezierPath];

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

        [shapeTriangle moveToPoint:CGPointMake(s/2.0 * cos(-M_PI/2.0) + s/2.0 + 5 + i * 50,

                                               s/2.0 * sin(-M_PI/2.0) + s/2.0 + 10)];

        [shapeTriangle addLineToPoint:CGPointMake(s/2.0 * cos(-M_PI/2.0 + M_PI * 2.0/3.0) + s/2.0 + 5 + i * 50,

                                                  s/2.0 * sin(-M_PI/2.0 + M_PI * 2.0/3.0) + s/2.0 + 10)];

        [shapeTriangle addLineToPoint:CGPointMake(s/2.0 * cos(-M_PI/2.0 + M_PI * 4.0/3.0) + s/2.0 + 5 + i * 50,

                                                  s/2.0 * sin(-M_PI/2.0 + M_PI * 4.0/3.0) + s/2.0 + 10)];

        [shapeTriangle closePath];

    }

    [shapeTriangle moveToPoint:CGPointMake(0, 25)];

    [shapeTriangle addLineToPoint:CGPointMake(10, 25)];

    [shapeTriangle moveToPoint:CGPointMake(40, 25)];

    [shapeTriangle addLineToPoint:CGPointMake(60, 25)];

    [shapeTriangle moveToPoint:CGPointMake(90, 25)];

    [shapeTriangle addLineToPoint:CGPointMake(100, 25)];

    

    CAShapeLayer *l = [CAShapeLayer layer];

    l.path = shapeTriangle.CGPath;

    l.fillColor = [UIColor clearColor].CGColor;

    l.strokeColor = [UIColor whiteColor].CGColor;

    l.lineWidth = 3;

    

    return l;

}

– (CAShapeLayer *)createRectShape

{

    UIBezierPath *shapeCircle = [UIBezierPath bezierPathWithRect:CGRectMake(10, 10, 30, 30)];

    [shapeCircle appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(60, 10, 30, 30)]];

    [shapeCircle moveToPoint:CGPointMake(0, 25)];

    [shapeCircle addLineToPoint:CGPointMake(10, 25)];

    [shapeCircle moveToPoint:CGPointMake(40, 25)];

    [shapeCircle addLineToPoint:CGPointMake(60, 25)];

    [shapeCircle moveToPoint:CGPointMake(90, 25)];

    [shapeCircle addLineToPoint:CGPointMake(100, 25)];

    

    CAShapeLayer *l = [CAShapeLayer layer];

    l.path = shapeCircle.CGPath;

    l.fillColor = [UIColor clearColor].CGColor;

    l.strokeColor = [UIColor whiteColor].CGColor;

    l.lineWidth = 3;

    

    return l;

}

– (void)createFace

{

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

    v.center = CGPointMake(CGRectGetMidX(self.view.bounds), 120);

    v.layer.cornerRadius = 100;

    v.backgroundColor = [UIColor orangeColor];

    [self.view addSubview:v];

    

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

        UIView *eye = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];

        eye.center = CGPointMake(50 + i * 100, 100);

        eye.backgroundColor = [UIColor blackColor];

        [v addSubview:eye];

    }

    

    UIView *mouth = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 10)];

    mouth.center = CGPointMake(100, 160);

    mouth.backgroundColor = [UIColor blackColor];

    [v addSubview:mouth];

    

    self.face = v;

}

– (void)buttonAction:(UIButton *)sender

{

    sender.bounds = CGRectMake(0, 0, 100, 60);

    UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

    APLPositionToBoundsMapping *buttonBoundsDynamicItem = [[APLPositionToBoundsMapping alloc] initWithTarget:(id)sender];

    UIAttachmentBehavior *attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:buttonBoundsDynamicItem attachedToAnchor:buttonBoundsDynamicItem.center];

    [attachmentBehavior setFrequency:2.0];

    [attachmentBehavior setDamping:0.3];

    [animator addBehavior:attachmentBehavior];

    

    UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[buttonBoundsDynamicItem] mode:UIPushBehaviorModeInstantaneous];

    pushBehavior.angle = M_PI_4;

    pushBehavior.magnitude = 2.0;

    [animator addBehavior:pushBehavior];

    

    [pushBehavior setActive:TRUE];

    

    self.animator = animator;

    

    [self wearGlass:sender];

}

– (void)wearGlass:(UIView *)glass

{

    NSArray *shapes = @[[self createCircleShape]

                        ,[self createTriangleShape]

                        ,[self createRectShape]];

    

    [self.face.layer.sublayers enumerateObjectsUsingBlock:^(CALayer *obj, NSUInteger idx, BOOL *stop) {

        if ([obj.name isEqualToString:@”glass”]) {

            [obj removeFromSuperlayer];

        }

    }];

    

    CAShapeLayer *l = shapes[glass.tag];

    l.name = @”glass”;

    l.strokeColor = [UIColor blueColor].CGColor;

    l.transform = CATransform3DMakeScale(2.0, 2.0, 1.0);

    l.position = CGPointMake(l.position.x, l.position.y + 50);

    

    [self.face.layer addSublayer:l];

}

@end