iPhoneカード開閉

カードをとじて、ひらいてするiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

@import SceneKit;

@interface ViewController ()

@property (nonatomic, weak) SCNView *sceneView;

@property (nonatomic) BOOL open;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    [self setupScene];

    [self createCards];

    [self createCamera];

}

– (void)setupScene {

    SCNView *sv = [[SCNView alloc] initWithFrame:self.view.bounds];

    sv.backgroundColor = [self color:0];

    sv.scene = [SCNScene scene];

    [self.view addSubview:sv];

    

    sv.autoenablesDefaultLighting = YES;

    

    self.sceneView = sv;

}

– (void)createCards {

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

        

        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(-10, –16, 20, 32) cornerRadius:2];

        SCNShape *s1 = [SCNShape shapeWithPath:path extrusionDepth:0.1];

        s1.firstMaterial.diffuse.contents = [self color:3];

        SCNNode *box1 = [SCNNode nodeWithGeometry:s1];

        

        [path applyTransform:CGAffineTransformMakeScale(0.9, 0.92)];

        SCNShape *s2 = [SCNShape shapeWithPath:path extrusionDepth:0.101];

        s2.firstMaterial.diffuse.contents = [self color:2];

        SCNNode *box2 = [SCNNode nodeWithGeometry:s2];

        

        SCNNode *mark = [SCNNode node];

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

            SCNBox *m = [SCNBox boxWithWidth:1 height:1 length:0.103 chamferRadius:0];

            m.firstMaterial.diffuse.contents = [self color:4];

            SCNNode *n = [SCNNode nodeWithGeometry:m];

            n.position = SCNVector3Make(j * 1.6, 12, 0);

            [mark addChildNode:n];

        }

        

        SCNNode *boxNode = [SCNNode node];

        boxNode.name = [NSString stringWithFormat:@”card%d”, i];

        boxNode.position = SCNVector3Make(0, 0, i * 0.1);

        [boxNode addChildNode:box1];

        [boxNode addChildNode:box2];

        [boxNode addChildNode:mark];

        [self.sceneView.scene.rootNode addChildNode:boxNode];

        

        boxNode.pivot = SCNMatrix4MakeTranslation(8, –15, 0);

        boxNode.transform = SCNMatrix4Rotate(boxNode.transform, –1.2 + (0.5 * i), 0, 0, 1);

        self.open = YES;

    }

}

– (void)createCamera {

    SCNNode *camera = [SCNNode node];

    camera.camera = [SCNCamera camera];

    camera.position = SCNVector3Make(0, 5, 70);

    [self.sceneView.scene.rootNode addChildNode:camera];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    self.open = !self.open;

    

    if (self.open) {

        [self.sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) {

            if ([child.name hasPrefix:@”card”]) {

                [child runAction:[SCNAction rotateToX:0 y:0 z:0 duration:0.5]];

            }

        }];

    } else {

        

        [self.sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) {

            if ([child.name hasPrefix:@”card”]) {

                int i = [[child.name substringFromIndex:4] intValue];

                [child runAction:[SCNAction rotateToX:0 y:0 z:-1.2 + (0.5 * i) duration:0.5]];

            }

        }];

    }

}

#define ColorHex(rgb) [UIColor colorWithRed:((rgb & 0xFF0000) >> 16)/255.0 green:((rgb & 0xFF00) >> 8)/255.0 blue:(rgb & 0xFF)/255.0 alpha:1.0]

– (UIColor *)color:(int)i {

    if (i > 4) return nil;

    int colors[] = {0x99C430, 0xD3CEAA, 0xFBF7E4, 0x424242, 0x8E001C};

    return ColorHex(colors[i]);

}

@end