4 本の指の回転を検出できるジェスチャ認識機能を作成しようとしています (ボリューム ノブを回転させた場合と同様)。
主なアイデアは、UIRotateGestureRecognizer のサブクラスを作成し、そのメソッドをオーバーライドすることでした。-touchesBegan
I detect the number of touch で、数が 4 未満の場合、ジェスチャの状態は失敗です。
その後、凸包の直径を求めるアルゴリズムに位置点を渡します。考えてみると、指が頂点であり、最大距離で 2 つの頂点を見つける必要があります。これら 2 つのポイントを取得したら、ivar として参照し、スーパークラスに渡します。これは、2 本の指だけで簡単に回転できるためです。
それは動作しません:
- タッチの検出はかなり難しいようです
-touchesHasMoved
と呼ばれることはめったにありません- 呼び出されると、ほとんどの場合ハングします
誰かが私を助けることができますか?
コードは次のとおりです。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (touches.count<4) {
//FAIL
self.state = UIGestureRecognizerStateFailed;
return;
}
//Find the diameter of the convex hull
NSArray * touchesArray = [touches allObjects];
NSMutableArray * pointsArray = @[].mutableCopy;
for (UITouch * touch in touchesArray) {
[pointsArray addObject:[NSValue valueWithCGPoint:[touch locationInView:touch.view]]];
}
DiameterType convexHullDiameter = getDiameterFromPoints(pointsArray);
CGPoint firstPoint = convexHullDiameter.firstPoint;
CGPoint secondPoint = convexHullDiameter.secondPoint;
for (UITouch * touch in touchesArray) {
if (CGPointEqualToPoint([touch locationInView:touch.view], firstPoint) ) {
self.fistTouch = touch;
}
else if (CGPointEqualToPoint([touch locationInView:touch.view], secondPoint)){
self.secondTouch = touch;
}
}
//Calculating the rotation center as a mid point between the diameter vertices
CGPoint rotationCenter = (CGPoint) {
.x = (convexHullDiameter.firstPoint.x + convexHullDiameter.secondPoint.x)/2,
.y = (convexHullDiameter.firstPoint.y + convexHullDiameter.secondPoint.y)/2
};
self.rotationCenter = rotationCenter;
//Passing touches to super as a fake rotation gesture
NSSet * touchesSet = [[NSSet alloc] initWithObjects:self.fistTouch, self.secondTouch, nil];
[super touchesBegan:touchesSet withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (touches.count<4) {
self.state = UIGestureRecognizerStateFailed;
return;
}
[super touchesMoved:[[NSSet alloc] initWithObjects:self.fistTouch, self.secondTouch, nil] withEvent:event];
}
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:[[NSSet alloc] initWithObjects:self.fistTouch, self.secondTouch, nil] withEvent:event];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:[[NSSet alloc] initWithObjects:self.fistTouch, self.secondTouch, nil] withEvent:event];
}