CreateJSを使ってみる – 図形のドラッグ で、やったようなのをiOSでやってみる。
 イメージ図。今回は動かす図形は、駒形にしてみた。
 
CALayer をあつかうので、QuartzCore フレームワークを加える。
 
 
iPhoneアプリ開発のコツとツボ35
 を参考にしています。
 
動かす図形部分は、CALayerを継承したクラス KomaLayerにした。
 
タッチについて。
 iOSでマルチタッチができるアプリを作るための初歩 – @IT
 イベント処理ガイド(iOS用) apple (pdf)
CALayerとのhitTest。
 
 図 – 駒と矩形。
 上図のような場合、矩形部分がヒットとなる。アルファ値がゼロの部分をヒットとしないようにするには、自力で実装する必要あり。
 (こちらのブログで、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
 
 