BMI表のiPhoneアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@import SpriteKit;
@interface ViewController () <UITextFieldDelegate>
@property (nonatomic, weak) SKScene *scene;
@property (nonatomic, strong) NSMutableDictionary *uicomponent;
@end
@implementation ViewController
– (void)viewDidLoad {
[super viewDidLoad];
[self setupScene];
[self createBMIChart];
[self createUserControl];
}
– (void)setupScene {
SKView *sv = [[SKView alloc] initWithFrame:self.view.bounds];
SKScene *s = [SKScene sceneWithSize:sv.frame.size];
s.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
[sv presentScene:s];
[self.view addSubview:sv];
self.scene = s;
}
// … cpu heavy …
– (void)createBMIChart {
float mw = 10;
CGRect rect = CGRectMake(0, 0, CGRectGetMaxX(self.view.bounds) – 2*mw, CGRectGetMaxX(self.view.bounds) – 2*mw);
SKShapeNode *chart = [SKShapeNode shapeNodeWithRect:rect];
chart.name = @”chart”;
chart.lineWidth = 1;
chart.strokeColor = [UIColor colorWithWhite:0.1 alpha:1];
chart.position = CGPointMake(mw, CGRectGetMidX(self.view.bounds) + 50);
[self.scene addChild:chart];
float xmax = CGRectGetMaxX(rect);
float ymax = CGRectGetMaxY(rect);
float dx = 120.0 / xmax; // 40kg ~ 160kg
float dy = 55.0 / ymax; // 1.45m ~ 2.0m
for (int i=0; i<xmax; i+=10) {
for (int j=0; j<ymax; j+=10) {
float bmi = [self bmiFromMass:dx*i + 40 height:dy*j + 145];
UIColor *color = ^{
if (bmi < 18.5) return [[self color:0] colorWithAlphaComponent:0.6];
else if (bmi < 25) return [[self color:1] colorWithAlphaComponent:0.6];
else if (bmi < 30) return [[self color:2] colorWithAlphaComponent:0.6];
else return [[self color:3] colorWithAlphaComponent:0.6];
}();
SKSpriteNode *dot = [SKSpriteNode spriteNodeWithColor:color size:CGSizeMake(6, 6)];
dot.position = CGPointMake(i + 3, j + 3);
[chart addChild:dot];
}
}
}
– (void)createUserControl {
self.uicomponent = [NSMutableDictionary dictionary];
for (int i=0; i<2; i++) {
UISlider *sl = [[UISlider alloc] init];
sl.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMaxY(self.view.bounds) – 150 + i*50);
[sl addTarget:self action:@selector(change:) forControlEvents:UIControlEventValueChanged];
if (i == 0) {
sl.minimumValue = 145;
sl.maximumValue = 200;
sl.value = 160;
} else {
sl.minimumValue = 40;
sl.maximumValue = 160;
sl.value = 60;
}
[self.view addSubview:sl];
UILabel *l = [[UILabel alloc] init];
l.center = CGPointMake(sl.center.x + 80, sl.center.y);
l.text = [NSString stringWithFormat:@”%.1f”, sl.value];
[l sizeToFit];
[self.view addSubview:l];
[self.uicomponent setObject:sl forKey:[NSString stringWithFormat:@”slider%d”,i]];
[self.uicomponent setObject:l forKey:[NSString stringWithFormat:@”label%d”,i]];
}
}
– (void)change:(UISlider*)sender {
UISlider *sl0 = [self.uicomponent valueForKey:@”slider0″];
UISlider *sl1 = [self.uicomponent valueForKey:@”slider1″];
UILabel *l0 = [self.uicomponent valueForKey:@”label0″];
UILabel *l1 = [self.uicomponent valueForKey:@”label1″];
l0.text = [NSString stringWithFormat:@”%.1f cm”, sl0.value];
[l0 sizeToFit];
l1.text = [NSString stringWithFormat:@”%.1f kg”, sl1.value];
[l1 sizeToFit];
SKNode *chart = [self.scene childNodeWithName:@”chart”];
float xmax = CGRectGetMaxX(chart.frame);
float ymax = CGRectGetMaxY(chart.frame);
float dx = 120.0 / xmax; // 40kg ~ 160kg
float dy = 55.0 / ymax; // 1.45m ~ 2.0m
float x = (sl1.value – 40) / dx;
float y = (sl0.value – 145) / dy;
SKShapeNode *n = (SKShapeNode *)[chart childNodeWithName:@”bmi”];
if (!n) {
n = [SKShapeNode shapeNodeWithCircleOfRadius:10];
n.name = @”bmi”;
n.fillColor = [UIColor purpleColor];
[chart addChild:n];
}
n.position = CGPointMake(x, y);}
– (float)bmiFromMass:(float)mass height:(float)height {
if (height == 0) return 0;
return mass / pow(height * 0.01, 2);
}
#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 > 3) return nil;
int colorCodes[] = {0xFFFFFF, 0xD4A815, 0xFFAF25, 0xC70500};
return ColorHex(colorCodes[i]);
}
@end