二分木の木を表示する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