iPhone二分木

二分木の木を表示するiPhoneアプリのサンプルコードを描いてみます。

今回使った画像


動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#pragma mark – purupuru item

@interface PuruPuruItem : NSObject <UIDynamicItem>

@property (nonatomic, weak) UIButton *btn;

@end

@implementation PuruPuruItem

– (CGRect)bounds

{

    return self.btn.bounds;

}

– (CGPoint)center

{

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

}

– (void)setCenter:(CGPoint)center

{

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

}

– (CGAffineTransform)transform

{

    return self.btn.transform;

}

– (void)setTransform:(CGAffineTransform)transform

{

    self.btn.transform = transform;

}

@end

#pragma mark – main

@interface ViewController ()

@property (nonatomic, weak) UIButton *plusN;

@property (nonatomic, weak) UILabel *score;

@property (nonatomic) CGRect button1Bounds;

@property (nonatomic, strong) UIDynamicAnimator *animator;

@property int count;

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    [self createPlusNButton];

    

    UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(230, 30, 100, 50)];

    l.numberOfLines = 0;

    l.text = @”N=0\nlogN=1″;

    [self.view addSubview:l];

    self.score = l;

}

-(void)createPlusNButton

{

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

    [btn setImage:[UIImage imageNamed:@”nButton”] forState:UIControlStateNormal];

    [btn sizeToFit];

    btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

    btn.contentVerticalAlignment = UIControlContentHorizontalAlignmentFill;

    btn.center = CGPointMake(160, 60);

    [self.view addSubview:btn];

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

    self.plusN = btn;

    self.button1Bounds = btn.bounds;

}

– (void)tapN

{

    self.plusN.bounds = self.button1Bounds;

    

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

    PuruPuruItem *purupuruBtn = [[PuruPuruItem alloc] init];

    purupuruBtn.btn = self.plusN;

    

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

    [attachmentBehavior setFrequency:2.0];

    [attachmentBehavior setDamping:0.1];

    [animator addBehavior:attachmentBehavior];

    

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

    pushBehavior.angle = M_PI_4;

    pushBehavior.magnitude = 2.0;

    [animator addBehavior:pushBehavior];

    

    [pushBehavior setActive:TRUE];

    

    self.animator = animator;

    

    [self createTreeNode];

}

– (void)createTreeNode

{

    int nodeCount = (int)pow(2,self.count);

    int log2N = (int)log2(nodeCount);

    self.score.text = [NSString stringWithFormat:@”N=%d\nlogN=%d”, nodeCount, log2N];

    

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

        float x = (i%2) ? i/2 * 30 + 175 : i/2 * (-30) + 145;

        if (self.count == 0) x = 160;

        float y = self.count * 60 + 120;

        UILabel *tNode = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];

        tNode.center = CGPointMake(x, y);

        tNode.text = [NSString stringWithFormat:@”n/%d”, log2N + 1];

        tNode.font = [UIFont boldSystemFontOfSize:16];

        tNode.textAlignment = NSTextAlignmentCenter;

        tNode.backgroundColor = [UIColor greenColor];

        tNode.textColor = [UIColor whiteColor];

        [self.view addSubview:tNode];

        

        float dx = 160 – x;

        float dy = 120 – y;

        tNode.transform = CGAffineTransformMakeTranslation(dx, dy);

        [UIView animateWithDuration:0.5 animations:^{

            tNode.transform = CGAffineTransformMakeTranslation(dx, 0);

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:0.5 animations:^{

                tNode.transform = CGAffineTransformIdentity;

            }];

        }];

    }

    

    // zoom

    if (nodeCount > 10) {

        [UIView animateWithDuration:1.0 animations:^{

            self.view.transform = CGAffineTransformMakeScale(10.0/nodeCount, 10.0/nodeCount);

        }];

    }

    

    self.count++;

    

}

@end