我试图创建一个手势识别器,能够检测4个手指的旋转(类似于当你旋转一个音量旋钮)。
其主要思想是创建UIRotateGestureRecognizer的子类并重写其方法。在-touchesBegan中,我检测到触摸的次数,如果数量低于4,则手势的状态将失败。
在此之后,我将定位点传递给一种算法,该算法可以找到凸包的直径。如果你想一想,你的手指就是顶点,我只需要找到最大距离的两个顶点。得到这两点,我把它们称为伊瓦尔,并把它们传递给超类,因为这是一个简单的旋转,只用两个手指。
这不管用:
-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];
}发布于 2013-12-02 06:02:01
最初检测困难的原因是,所有的接触可能都不是同时开始的。touchesBegan可能会被多次调用,因为屏幕上会有单独的触摸。您可以使用事件参数查询使用event.allTouches进行的所有当前操作。因此,您当前触发失败手势的方法将不起作用。如果touches.count是<4时,则不应该将状态设置为fail,而应该只返回event.allTouches.count <4时。如果第四次触摸在第一次触摸后的特定时间内没有发生,则可以使用计时器将状态设置为失败。
touchesMoved可能有问题,因为事件对象中的触点与传递给超级程序的集合中的触点不匹配。
发布于 2013-11-26 20:14:18
如果你想一想,你的手指就是顶点,我只需要找到最大距离的两个顶点。
我认为这在实践中是行不通的,即使你能够欺骗UIGestureRecognizer。
这就是我如何以‘正确’的方式实现算法:
new(i) - old(i) divided by distance to center> 0.5),则失败。恭喜您,您现在有了旋转角(以弧度度量)。
发布于 2013-11-26 14:11:32
如果我有足够的代表,我会把这个写在评论里。
[super touchesMoved:[[NSSet alloc] initWithObjects:self.fistTouch, self.secondTouch, nil] withEvent:event];您使用的是名为fistTouch的东西,听起来不像您想要的。我猜你想要firstTouch。
此外,手势之间可能会发生冲突,而这些手势之间的冲突可能会压倒彼此。你知道iOS7中有一个四指变焦,这是一个全系统的手势吗?另外,应用程序中的4指变焦会关闭它。
https://stackoverflow.com/questions/19662900
复制相似问题