我想检测从屏幕右下角开始到中间的两指对角线滑动。我尝试添加 UISwipeGestureRecognizer ,其方向设置为“UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionLeft”,但由于处理程序被调用,即使我从屏幕中间开始滑动到左上角也没有任何效果。
我需要子类 UIGestureRecognizer 还是可以使用 touchesBegan 和 touchesMoved 处理这个?
原因的touches方法可以做每一个Gesture,从ios3.2开始支持Gesture。我可以给你一个简单的代码,你可以自己修改。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
isTwoFingersBegin = NO;
isTwoFingersEnd = NO;
UITouch *touch = [touches anyObject];
UIView *touchView = [touch view];
if ([touches count] == 2)
{
isTwoFingersBegin = YES;
}
touchStartPoint = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
isSwip = YES;
}
#define TOUCH_MOVE_EFFECT_DIST 30
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
UIView *touchView = [touch view];
touchEndPoint = [touch locationInView:self.view];
if ([touches count] == 2)
{
isTwoFingersEnd = YES;
}
CGPoint deltaVector = CGPointMake(touchEndPoint.x - touchStartPoint.x, touchEndPoint.y - touchStartPoint.y);
if (fabsf(deltaVector.x) > TOUCH_MOVE_EFFECT_DIST
&&fabsf(deltaVector.y) > TOUCH_MOVE_EFFECT_DIST
&& isSwip &&isTwoFingersBegin&&isTwoFingersEnd) {
theSwipGesture=RightUpGesture;
}
else if (fabsf(deltaVector.x) <- TOUCH_MOVE_EFFECT_DIST
&& fabsf(deltaVector.y) <- TOUCH_MOVE_EFFECT_DIST
&& isSwip&&isTwoFingersBegin&&isTwoFingersEnd) {
theSwipGesture=LeftDownGesture;
}
isSwip = NO;
}
无论如何touchesBegan
,您需要将其子类化才能使用。touchesMoved
我会按照UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionLeft
你说的做,然后设置两个CGRect
s,一个用于可接受的起点,一个用于可接受的终点。然后使用该UIGestureRecognizerDelegate
方法gestureRecognizer:shouldReceiveTouch:
,使用 . 检查触摸点是否在可接受的起始矩形内CGRectContainsPoint()
。然后(我认为)在您的UISwipeGestureRecognizer
子类中覆盖touchesEnded:withEvent:
,并检查最终触摸是否在可接受的矩形中。如果不是,请将状态设置为UIGestureRecognizerStateCancelled
(或者您应该取消手势)。还要确保它附加到的视图具有其multipleTouchEnabled
属性集。我实际上还没有尝试过,但是应该这样做。祝你好运!
编辑
实际上,如果您不想担心可接受的起点/终点的特定 rect 值,并使其与设备无关,您可以这样做:
//swap in whatever percentage of the screen's width/height you want in place of ".75f"
//set the origin for acceptable start points
CGFloat startRect_x = self.view.frame.size.width * .75f;
CGFloat startRect_y = self.view.frame.size.height * .75f;
//set the size
CGFloat rectWidth = self.view.frame.size.width - startRect_x;
CGFloat rectHeight = self.view.frame.size.height - startRect_y;
//make the acceptable start point rect
CGRect startRect = CGRectMake(startRect_x, startRect_y, rectWidth, rectHeight);
//set the origin for the accepable end points
CGFloat endRect_x = self.view.center.x - rectWidth/2;
CGFloat endRect_y = self.view.center.y - rectHeight/2;
//make the acceptable end point rect
CGRect endRect = CGRectMake(endRect_x, endRect_y, rectWidth, rectHeight);
你可以使用一个UIPanGestureRecognizer
- (void)viewPanned:(UIPanGestureRecognizer *)panGR
{
CGPoint translation = [panGR translationInView:self];
CGFloat threshold = self.bounds.size.width/2;
// Detect
Direction direction = DirectionUnknown;
if (translation.x > threshold) {
if (translation.y > threshold) {
direction = DirectionBottomRight;
} else if (translation.y < -threshold) {
direction = DirectionTopRight;
} else {
direction = DirectionRight;
}
} else if (translation.x < -threshold) {
if (translation.y > threshold) {
direction = DirectionBottomLeft;
} else if (translation.y < -threshold) {
direction = DirectionTopLeft;
} else {
direction = DirectionLeft;
}
} else {
if (translation.y > threshold) {
direction = DirectionBottom;
} else if (translation.y < -threshold) {
direction = DirectionTop;
}
}
}
一种可能的解决方案是在 iPhone 屏幕上绘制一组可能开始滑动的坐标,以及另一个可能结束滑动的坐标。然后在touchesBegan:
andtouchesMoved:
方法中,您可以比较滑动的起点和终点,并确定它是否符合对角线。
多谢你们!
我最终在 touchesBegan、touchesMoved 和 touchesEnded 中编写了自定义代码,而其他工作就像魅力一样。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] == 2) {
CGPoint nowPoint = [[touches anyObject] locationInView:self];
if( nowPoint.x >= ALLOWED_X)
swipeUp = YES;
}
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
if ([touches count] == 2 && swipeUp) {
CGPoint nowPoint = [[touches anyObject] locationInView:self];
CGPoint prevPoint = [[touches anyObject] previousLocationInView:self];
if( nowPoint.x <= prevPoint.x && nowPoint.y <= prevPoint.y){
}
else {
swipeUp = NO;
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
CGPoint nowPoint = [[touches anyObject] locationInView:self];
if ([touches count] == 2 && swipeUp && nowPoint.x <= DELTA_X && nowPoint.y <= DELTA_Y) {
NSLog(@"Invoke Method");
}
swipeUp = NO;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
swipeUp = NO;
}