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
