How to recognize swipe in all 4 directions?
我需要识别所有方向(向上/向下/向左/向右)的滑动。不是同时发生的,但我需要识别它们。
我尝试过:
1 2 3 4 5 6 7 | UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeRecognizer:)]; Swipe.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp); [self.view addGestureRecognizer:Swipe]; [Swipe release]; |
但
上没有任何内容
这是SwipeRecognizer的代码:
1 2 3 4 5 6 7 8 9 10 | - (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender { if ( sender.direction == UISwipeGestureRecognizerDirectionLeft ) NSLog(@" *** SWIPE LEFT ***"); if ( sender.direction == UISwipeGestureRecognizerDirectionRight ) NSLog(@" *** SWIPE RIGHT ***"); if ( sender.direction == UISwipeGestureRecognizerDirectionDown ) NSLog(@" *** SWIPE DOWN ***"); if ( sender.direction == UISwipeGestureRecognizerDirectionUp ) NSLog(@" *** SWIPE UP ***"); } |
我该怎么做?如何将所有不同的方向分配给我的Swipe对象?
您可以这样设置方向
1 2 3 4 5 | UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeRecognizer:)]; Swipe.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp); |
这就是获得回调的方向??,因此所有测试均失败是正常的。如果您有
1 2 3 4 5 6 7 8 9 10 | - (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender { if ( sender.direction | UISwipeGestureRecognizerDirectionLeft ) NSLog(@" *** SWIPE LEFT ***"); if ( sender.direction | UISwipeGestureRecognizerDirectionRight ) NSLog(@" *** SWIPE RIGHT ***"); if ( sender.direction | UISwipeGestureRecognizerDirectionDown ) NSLog(@" *** SWIPE DOWN ***"); if ( sender.direction | UISwipeGestureRecognizerDirectionUp ) NSLog(@" *** SWIPE UP ***"); } |
测试将会成功(但是所有测试都会成功,因此您不会从测试中获取任何信息)。如果要区分不同方向上的滑动,则需要单独的手势识别器。
编辑
如评论中所指出,请参见此答案。显然,这甚至行不通。您应该只向一个方向滑动即可使生活更轻松。
我以前确实遇到过这个确切的问题。我最终要做的是创建一个UIView子类,重写
这是基本概念:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #import"OmnidirectionalControl.h" typedef NS_ENUM(NSInteger, direction) { Down = 0, DownRight = 1, Right = 2, UpRight = 3, Up = 4, UpLeft = 5, Left = 6, DownLeft = 7 }; @interface OmnidirectionalControl () @property (nonatomic) CGPoint startTouch; @property (nonatomic) CGPoint endTouch; @end -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { self.startTouch = [[touches allObjects][0] locationInView:self]; } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { self.lastTouch = [[[touches allObjects] lastObject] locationInView:self]; NSLog(@"Direction: %d", [self calculateDirectionFromTouches]); } -(direction)calculateDirectionFromTouches { NSInteger xDisplacement = self.lastTouch.x-self.startTouch.x; NSInteger yDisplacement = self.lastTouch.y-self.startTouch.y; float angle = atan2(xDisplacement, yDisplacement); int octant = (int)(round(8 * angle / (2 * M_PI) + 8)) % 8; return (direction) octant; } |
为简单起见,在
不幸的是,您不能使用
我终于找到了最简单的答案,如果您同意,请将其标记为答案。
如果只有一个方向的平移锅,则只需说:
[myPanRecogznier requireGestureRecognizerToFail:mySwipeRecognizer];
但是,如果有两次或多次滑动,则无法将数组传递给该方法。为此,您需要实现UIGestureRecognizerDelegate。
例如,如果要识别2次滑动(左右滑动)并且还希望允许用户平移,则可以将手势识别器定义为属性或实例变量,然后将VC设置为委托在摇动手势识别器上:
1 2 3 4 5 6 7 8 9 | _swipeLeft = [[UISwipeGestureRecognizer alloc] ...]; // use proper init here _swipeRight = [[UISwipeGestureRecognizer alloc] ...]; // user proper init here _swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft; _swipeRight.direction = UISwipeGestureRecognizerDirectionRight; _pan = [[UIPanGestureRecognizer alloc] ...]; // use proper init here _pan.delegate = self; // then add recognizers to your view |
然后,您实现-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer应该需要FailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer委托方法,如下所示:
1 2 3 4 5 6 7 8 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { if (gestureRecognizer == _pan && (otherGestureRecognizer == _swipeLeft || otherGestureRecognizer == _swipeRight)) { return YES; } return NO; } |
这告诉平移手势识别器仅在无法识别左右滑动时才起作用-完美!
希望在将来,Apple会让我们将数组传递给requireGestureRecognizerToFail:方法。
您只能通过SwipeGesture添加一个对角线,然后...
1 2 3 4 5 6 7 | UISwipeGestureRecognizer *swipeV = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)]; UISwipeGestureRecognizer *swipeH = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)]; swipeH.direction = ( UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight ); swipeV.direction = ( UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown ); [self addGestureRecognizer:swipeH]; [self addGestureRecognizer:swipeV]; self.userInteractionEnabled = YES; |
使用UIPanGestureRecogizer并检测您关心的滑动方向。有关详细信息,请参见UIPanGestureRecognizer文档。 -rrh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // add pan recognizer to the view when initialized UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRecognized:)]; [panRecognizer setDelegate:self]; [self addGestureRecognizer:panRecognizer]; // add to the view you want to detect swipe on -(void)panRecognized:(UIPanGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateBegan) { // you might want to do something at the start of the pan } CGPoint distance = [sender translationInView:self]; // get distance of pan/swipe in the view in which the gesture recognizer was added CGPoint velocity = [sender velocityInView:self]; // get velocity of pan/swipe in the view in which the gesture recognizer was added float usersSwipeSpeed = abs(velocity.x); // use this if you need to move an object at a speed that matches the users swipe speed NSLog(@"swipe speed:%f", usersSwipeSpeed); if (sender.state == UIGestureRecognizerStateEnded) { [sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure if (distance.x > 0) { // right NSLog(@"user swiped right"); } else if (distance.x < 0) { //left NSLog(@"user swiped left"); } if (distance.y > 0) { // down NSLog(@"user swiped down"); } else if (distance.y < 0) { //up NSLog(@"user swiped up"); } // Note: if you don't want both axis directions to be triggered (i.e. up and right) you can add a tolerence instead of checking the distance against 0 you could check for greater and less than 50 or 100, etc. } } |
此状态字中的状态代码
///如果您只想从上,下,左和右单拨动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | if (sender.state == UIGestureRecognizerStateEnded) { [sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure if (distance.x > 0 && abs(distance.x)>abs(distance.y)) { // right NSLog(@"user swiped right"); } else if (distance.x < 0 && abs(distance.x)>abs(distance.y)) { //left NSLog(@"user swiped left"); } if (distance.y > 0 && abs(distance.y)>abs(distance.x)) { // down NSLog(@"user swiped down"); } else if (distance.y < 0 && abs(distance.y)>abs(distance.x)) { //up NSLog(@"user swiped up"); } } |
这可能不是最佳解决方案,但是您始终可以为要检测的每个滑动方向指定不同的UISwipeGestureRecognizer。
在viewDidLoad方法中,只需定义所需的UISwipeGestureRecognizer:
1 2 3 4 5 6 7 8 9 | - (void)viewDidLoad{ UISwipeGestureRecognizer *recognizerUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeUp:)]; recognizerUp.direction = UISwipeGestureRecognizerDirectionUp; [[self view] addGestureRecognizer:recognizerUp]; UISwipeGestureRecognizer *recognizerDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeDown:)]; recognizerDown.direction = UISwipeGestureRecognizerDirectionDown; [[self view] addGestureRecognizer:recognizerDown]; } |
然后只需实现相应的方法即可处理滑动:
1 2 3 4 5 6 7 8 9 10 11 12 | - (void)handleSwipeUp:(UISwipeGestureRecognizer *)sender{ if (sender.state == UIGestureRecognizerStateEnded){ NSLog(@"SWIPE UP"); } } - (void)handleSwipeDown:(UISwipeGestureRecognizer *)sender{ if (sender.state == UIGestureRecognizerStateEnded){ NSLog(@"SWIPE DOWN"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | UISwipeGestureRecognizer *Updown=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleGestureNext:)]; Updown.delegate=self; [Updown setDirection:UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp]; [overLayView addGestureRecognizer:Updown]; UISwipeGestureRecognizer *LeftRight=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleGestureNext:)]; LeftRight.delegate=self; [LeftRight setDirection:UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight]; [overLayView addGestureRecognizer:LeftRight]; overLayView.userInteractionEnabled=NO; -(void)handleGestureNext:(UISwipeGestureRecognizer *)recognizer { NSLog(@"Swipe Recevied"); } |