[iOS]図形のドラッグ

CreateJSを使ってみる – 図形のドラッグ で、やったようなのをiOSでやってみる。
イメージ図。今回は動かす図形は、駒形にしてみた。
image_dragAndDrop_iOS

Single View Application を作成。
スクリーンショット 2013-08-11 21.37.44

CALayer をあつかうので、QuartzCore フレームワークを加える。
スクリーンショット 2013-09-08 23.25.40
add Quartz framework

iPhoneアプリ開発のコツとツボ35
を参考にしています。

動かす図形部分は、CALayerを継承したクラス KomaLayerにした。
スクリーンショット 2013-09-08 23.36.36

タッチについて。
iOSでマルチタッチができるアプリを作るための初歩 – @IT
イベント処理ガイド(iOS用) apple (pdf)

CALayerとのhitTest。
image_hitLayer
図 – 駒と矩形。
上図のような場合、矩形部分がヒットとなる。アルファ値がゼロの部分をヒットとしないようにするには、自力で実装する必要あり。
(こちらのブログで、CALayerのhitTestをXcode上で検証している模様を動画にしてある。
[UST配信] Core Animationレイヤーのヒットテストを検証してみる: Sazameki Blog

ソースコード。
ViewController.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "KomaLayer.h"

@interface ViewController : UIViewController

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
{
    KomaLayer* selectedLayer;

    CGPoint touchLastPoint;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.

    //  KomaLayer作成
    //colors red, orange, yellow, green, blue, indigo, violet
    NSArray* colors = @[@(0.0),@(0.06),@(0.17),@(0.3),@(0.66),@(0.73),@(0.84)];
    CGRect r = CGRectMake(0, 0, 44, 44);
    for (int i = 0; i < 7; i++) {
        KomaLayer* koma = [KomaLayer layer];
        koma.frame = r;
        koma.color = [UIColor colorWithHue:[colors[i] floatValue] saturation:1.0 brightness:1.0 alpha:0.8];
        //koma.backgroundColor = [UIColor colorWithHue:[colors[i] floatValue] saturation:0.3 brightness:1.0 alpha:1.0].CGColor;
        koma.position = CGPointMake(0 + r.size.width / 2,
                                    44 * i + r.size.height / 2);

        [koma setNeedsDisplay];
        [self.view.layer addSublayer:koma];
    }

}

- (CALayer*)hitLayer:(UITouch*)touch
{
    CGPoint touchPoint = [touch locationInView:self.view];
    touchPoint = [self.view.layer convertPoint:touchPoint toLayer:self.view.layer.superlayer];
    return [self.view.layer hitTest:touchPoint];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    selectedLayer = nil;
    UITouch* touch = [touches anyObject];
    CALayer* layer = [self hitLayer:touch];

    CGPoint touchPoint = [touch locationInView:self.view];
    touchLastPoint = touchPoint;

    [self select:layer];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch* touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:self.view];
    CGPoint touchOffsetPoint = CGPointMake(touchPoint.x - touchLastPoint.x,
                                   touchPoint.y - touchLastPoint.y);
    touchLastPoint = touchPoint;
    if (selectedLayer != nil) {
        CGFloat px = selectedLayer.position.x;
        CGFloat py = selectedLayer.position.y;

        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        selectedLayer.position = CGPointMake(px + touchOffsetPoint.x, py + touchOffsetPoint.y);
        [CATransaction commit];

    }
}

/*
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}
 */

- (void)select:(KomaLayer*)layer
{
    if ((layer == self.view.layer) || (layer == nil)) {
        selectedLayer = nil;
        return;
    }

    selectedLayer = layer;
    return;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

KomaLayer.h

#import <QuartzCore/QuartzCore.h>

@interface KomaLayer : CALayer
@property UIColor* color;

@end

KomaLayer.m

#import "KomaLayer.h"

@implementation KomaLayer

- (void)drawKoma:(CGContextRef)ctx
{
    CGContextBeginPath(ctx);
    CGContextMoveToPoint(ctx, 0, 0);
    CGContextAddLineToPoint(ctx, 0.42, 0.3);
    CGContextAddLineToPoint(ctx, 0.5, 1.0);
    CGContextAddLineToPoint(ctx, -0.5, 1);
    CGContextAddLineToPoint(ctx, -0.42, 0.3);
    CGContextAddLineToPoint(ctx, 0, 0);
    CGContextClosePath(ctx);
    CGContextSetFillColorWithColor(ctx, self.color.CGColor);
    CGContextFillPath(ctx);
}

- (void)drawInContext:(CGContextRef)ctx
{
    // 座標変換
    CGContextTranslateCTM(ctx, self.bounds.size.width / 2.0, 0);
    CGContextScaleCTM(ctx, self.bounds.size.width, self.bounds.size.height);
    [self drawKoma:ctx];
}

@end

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください