集合AB

AかBどちらかの範囲内にある四角の数を数えるiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

@interface ViewController ()

@property (nonatomic, weak) UIView *space;

@property (nonatomic, weak) UIView *spaceA;

@property (nonatomic, weak) UIView *spaceB;

@property (nonatomic, weak) UIButton *btn;

@property (nonatomic, strong) UIDynamicItemBehavior *propertiesBehavior;

@property (nonatomic, strong) UIDynamicAnimator *animator;

@property (nonatomic, strong) NSMutableArray *nodes;

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    [self createLabel];

    [self createSpace];

    [self createButton];

    [self setupNode];

}

– (void)createLabel

{

    NSArray *text = [@”{A} =,{B} =,{A∩B} =” componentsSeparatedByString:@”,”];

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

        float y = 310 + 40 * i;

        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, y, 250, 50)];

        label.tag = i + 1;

        label.text = text[i];

        label.textAlignment = NSTextAlignmentLeft;

        [self.view addSubview:label];

    }

}

– (void)createSpace

{

    UIView *space = [[UIView alloc] initWithFrame:CGRectMake(20, 30, 280, 280)];

    space.backgroundColor = [UIColor greenColor];

    [self.view addSubview:space];

    

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

        

        float x = 90 + i * 100;

        

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

        v.layer.cornerRadius = CGRectGetMidX(v.bounds);

        v.layer.borderWidth = 5;

        v.layer.borderColor = [UIColor whiteColor].CGColor;

        v.center = CGPointMake(x, 180);

        [space addSubview:v];

        

        UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(x-20, 70, 40, 40)];

        l.text = i == 0 ? @”A” : @”B”;

        l.font = [UIFont boldSystemFontOfSize:30];

        l.textColor = [UIColor whiteColor];

        l.textAlignment = NSTextAlignmentCenter;

        l.backgroundColor = space.backgroundColor;

        [space addSubview:l];

        

        if (i==0) {

            self.spaceA = v;

        } else {

            self.spaceB = v;

        }

    }

    self.space = space;

}

– (void)createButton

{

    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(220, 340, 80, 80)];

    btn.backgroundColor = [UIColor brownColor];

    [btn setTitle:@”?” forState:UIControlStateNormal];

    [btn setTitleColor:[UIColor yellowColor] forState:UIControlStateHighlighted];

    btn.titleLabel.font = [UIFont boldSystemFontOfSize:60];

    [self.view addSubview:btn];

    

    [btn addTarget:self action:@selector(buttonTap) forControlEvents:UIControlEventTouchUpInside];

    self.btn = btn;

}

– (void)setupNode

{

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

    

    self.nodes = [NSMutableArray array];

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

        float x = arc4random() % 240;

        float y = arc4random() % 240;

        UIView *node = [[UIView alloc] initWithFrame:CGRectMake(x, y, 10, 10)];

        node.backgroundColor = [UIColor orangeColor];

        [self.space addSubview:node];

        [self.nodes addObject:node];

    }

    

    UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:self.nodes];

    collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;

    self.propertiesBehavior = [[UIDynamicItemBehavior alloc] initWithItems:self.nodes];

    self.propertiesBehavior.elasticity = 1.0;

    [animator addBehavior:self.propertiesBehavior];

    [animator addBehavior:collisionBehavior];

    

    UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:self.nodes mode:UIPushBehaviorModeInstantaneous];

    pushBehavior.pushDirection = CGVectorMake(0.1, 0.1);

    pushBehavior.active = YES;

    [animator addBehavior:pushBehavior];

    

    self.animator = animator;

}

– (void)buttonTap

{

    // stop

    [self.animator removeAllBehaviors];

    [self performSelector:@selector(calc) withObject:nil afterDelay:0.2];

}

– (void)calc

{

    int countA = 0;

    int countB = 0;

    int countAandB = 0;

    

    float r = CGRectGetMidX(self.spaceA.bounds);

    CGPoint a = self.spaceA.center;

    CGPoint b = self.spaceB.center;

    

    for (UIView *v in self.nodes) {

        

        float da = hypotf(a.x – v.center.x, a.y – v.center.y);

        if (da <= r) {

            countA++;

        }

        

        float db = hypotf(b.x – v.center.x, b.y – v.center.y);

        if (db <= r) {

            countB++;

        }

        

        if (da <= r && db <= r) {

            countAandB++;

        }

    }

    

    [self updateLabel:countA b:countB ab:countAandB];

}

– (void)updateLabel:(int)a b:(int)b ab:(int)ab

{

    NSArray *text = [@”{A} =,{B} =,{A∩B} =” componentsSeparatedByString:@”,”];

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

        UILabel *l = (UILabel *)[self.view viewWithTag:i+1];

        int num = i==0 ? a : i==1 ? b : ab;

        l.text = [NSString stringWithFormat:@”%@ %d”, text[i], num];

    }

    

    [self.btn setTitle:@”!” forState:UIControlStateNormal];

    [self.btn removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];

    [self.btn addTarget:self action:@selector(reset) forControlEvents:UIControlEventTouchUpInside];

}

– (void)reset

{

    [self.view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        [obj removeFromSuperview];

    }];

    

    self.animator = nil;

    

    [self createLabel];

    [self createSpace];

    [self createButton];

    [self setupNode];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

}

@end