iPhoneドロップスの歌

子供の本にドロップスの歌っていうのが載っていたので、ドロップが上から降ってくるようなiPhoneアプリのサンプルを描いてみます。今回はUIDynamicAnimatorというのを使ってみました。(※clearボタン付けたのですが、オブジェクト消すときにシミュレータだとメモリリークする気がします、UIDynamicAnimator使ったときのメモリ解放の作法が知りたい。。)

サンプルを動かすとこんな感じです

サンプルコード

#import “ViewController.h”

@interface ViewController () <UIDynamicAnimatorDelegate>

@property (strong, nonatomic) UIDynamicAnimator *animator;

@property (strong, nonatomic) UIGravityBehavior *gravity;

@property (strong, nonatomic) UICollisionBehavior *collider;

@property (weak, nonatomic) UIView *drop;

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor blackColor];

    

    [self setup];

}

– (void)setup

{

    [self.animator addBehavior:self.gravity];

    [self.animator addBehavior:self.collider];

    

    UIButton *clear = [UIButton buttonWithType:UIButtonTypeSystem];

    clear.frame = CGRectMake(10, 30, 60, 20);

    clear.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];

    [clear setTitle:@”clear” forState:UIControlStateNormal];

    [self.view addSubview:clear];

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

}

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

{

    CGPoint p = [[touches anyObject] locationInView:self.view];

    

    UIView *drop = [[UIView alloc] initWithFrame:(CGRect){.size = CGSizeMake(5, 5)}];

    drop.center = p;

    float hue = (arc4random() % 10) / 10.0;

    drop.backgroundColor = [UIColor colorWithHue:hue saturation:0.6 brightness:1.0 alpha:1.0];

    drop.layer.masksToBounds = YES;

    [self.view addSubview:drop];

    self.drop = drop;

}

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

{

    CGPoint p = [[touches anyObject] locationInView:self.view];

    CGPoint p0 = self.drop.center;

    

    float r = hypotf(p.x – p0.x, p.y – p0.y);

    self.drop.frame = CGRectMake(0, 0, r, r);

    self.drop.center = p0;

    self.drop.layer.cornerRadius = r/2.0;

}

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

{

    [self.gravity addItem:self.drop];

    [self.collider addItem:self.drop];

}

– (UIDynamicAnimator *)animator

{

    if (!_animator) {

        _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

        _animator.delegate = self;

    }

    return _animator;

}

– (UIGravityBehavior *)gravity

{

    if (!_gravity) {

        _gravity = [[UIGravityBehavior alloc] init];

        _gravity.magnitude = 0.9;

    }

    return _gravity;

}

– (UICollisionBehavior *)collider

{

    if (!_collider) {

        _collider = [[UICollisionBehavior alloc] init];

        _collider.translatesReferenceBoundsIntoBoundary = YES;

    }

    return _collider;

}

– (void)clear

{

    for (int i=0; i<[self.gravity.items count]; i++) {

        [self.gravity removeItem:self.gravity.items[i]];

        [self.collider removeItem:self.collider.items[i]];

    }

    [self.animator removeAllBehaviors];

    [self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

    

    

    self.gravity = nil;

    self.collider = nil;

    self.animator = nil;

    [self setup];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end