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