简体   繁体   English

设置UISwipeGestureRecognizer的方向

[英]Setting direction for UISwipeGestureRecognizer

I want to add simple swipe gesture recognition to my view based iPhone project. 我想在基于视图的iPhone项目中添加简单的滑动手势识别功能。 Gestures in all directions (right, down, left, up) should be recognized. 应识别所有方向(右,下,左,上)的手势。

It is stated in the docs for UISwipeGestureRecognizer: 它在UISwipeGestureRecognizer的文档中说明:

You may specify multiple directions by specifying multiple UISwipeGestureRecognizerDirection constants using bitwise-OR operands. 您可以通过使用按位或操作数指定多个UISwipeGestureRecognizerDirection常量来指定多个方向。 The default direction is UISwipeGestureRecognizerDirectionRight. 默认方向是UISwipeGestureRecognizerDirectionRight。

However for me it doesn't work. 但对我来说它不起作用。 When all four directions are OR'ed only left and right swipes are recognized. 当所有四个方向都被“或”时,仅识别左右滑动。

- (void)viewDidLoad {
    UISwipeGestureRecognizer *recognizer;

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionUp)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release]; 
    [super viewDidLoad];
}

-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe received.");
}

I fixed this with adding four recognizers to the view but I'm curious to know why didn't it work as advertised in docs? 我通过在视图中添加四个识别器来修复此问题,但我很想知道它为什么不像在文档中宣传的那样工作?

- (void)viewDidLoad {
    UISwipeGestureRecognizer *recognizer;

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionDown)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    [super viewDidLoad];
}

-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe received.");
}

Seems like there is a bug. 好像有一个bug。 You can specify the allowed direction(s) as you did. 您可以像指定的那样指定允许的方向。 But when you try to access the actual direction that triggered the swipe in the action selector method you still get the bit mask you originally set (for the allowed directions). 但是当您尝试访问动作选择器方法中触发滑动的实际方向时,您仍然会获得最初设置的位掩码(对于允许的方向)。

This means that checks for the actual direction will always fail when more than 1 direction is allowed. 这意味着当允许超过1个方向时,检查实际方向将始终失败。 You can see it for yourself quite easily when you output the value of 'direction' in the selector method (ie -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer ). 当你在选择器方法中输出'direction'的值时,你可以很容易地看到它(即-(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer )。

Filed a bug report (#8276386) to Apple. 向Apple提交了一份错误报告(#8276386)。

[Update] I got an answer from Apple saying that the behavior works as was intended. [更新]我从苹果公司得到了一个答案,说这个行为是按预期运作的。

So for example in a table view you can swipe left or right in a table view cell to trigger 'delete' (this would have directions of the swipe gesture set to left and right) 因此,例如在表格视图中,您可以在表格视图单元格中向左或向右滑动以触发“删除”(这将具有向左和向右设置的滑动手势的方向)

This means that the original workaround is the way it's supposed to be used. 这意味着原始的解决方法是它应该被使用的方式。 The direction property can only be used to get the gestures recognized correctly, but not in the method performed on a successful recognition to compare for the actual direction that triggered the recognition. direction属性只能用于正确识别手势,但不能用于成功识别时执行的方法,以比较触发识别的实际方向。

I noticed that left/right and up/down gestures work together in pairs, so you only need to specify two gesture recognizers. 我注意到左/右和上/下手势成对地一起工作,因此您只需要指定两个手势识别器。 And the docs do seem to be wrong. 而且文档似乎确实是错误的。

Well that sucks, I solved the problem by adding 2 gestures like Lars mentioned and that worked perfectly... 那太糟糕了,我通过添加Lars提到的两个手势解决了这个问题,并且工作得很好......

1) Left/Right 2) Up/Down 1)左/右2)上/下

  

UISwipeGestureRecognizer *swipeLeftRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [swipeLeftRight setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft )];
    [self.view addGestureRecognizer:swipeLeftRight];

    UISwipeGestureRecognizer *swipeUpDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [swipeUpDown setDirection:(UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown )];
    [self.view addGestureRecognizer:swipeUpDown];
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];

Now this is the didSwipe function 现在这是didSwipe函数

- (void) didSwipe:(UISwipeGestureRecognizer *)recognizer{
      if([recognizer direction] == UISwipeGestureRecognizerDirectionLeft){
          //Swipe from right to left
          //Do your functions here
      }else{
          //Swipe from left to right
          //Do your functions here
      }
 }

If you want it to detect all four directions, you'll need to create four instances, as you did in your work-around. 如果您希望它检测所有四个方向,则需要创建四个实例,就像在解决方法中所做的那样。

Here's Why : The same instance of UISwipeGestureRecognizer that you create is the instance that gets passed to the selector as sender. 这是为什么 :您创建的UISwipeGestureRecognizer的相同实例是作为发送方传递给选择器的实例。 So if you set it to recognize all four directions, it will return true for sgr.direction == xxx where xxx is any one of the four directions. 因此,如果您将其设置为识别所有四个方向,则对于sgr.direction == xxx将返回true,其中xxx是四个方向中的任何一个。

Here's an alternative work-around that involves less code (assumes ARC use): 这是一个替代解决方案 ,涉及更少的代码(假设ARC使用):

for(int d = UISwipeGestureRecognizerDirectionRight; d <= UISwipeGestureRecognizerDirectionDown; d = d*2) {
    UISwipeGestureRecognizer *sgr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    sgr.direction = d;
    [self.view addGestureRecognizer:sgr];
}

If your using Xcode 4.2 you can add Gesture Recognizers @ the storyboard and then link the GUI Gesture Recognizers to IBActions. 如果您使用Xcode 4.2,您可以在故事板上添加Gesture Recognizers,然后将GUI手势识别器链接到IBActions。

You can find the Gesture Recognizers in the Object Library of the Utility Pane (The bottom of the Right pane). 您可以在Utility Pane的对象库中找到Gesture Recognizers(右侧窗格的底部)。

Then its just a matter of Control-dragging to the appropriate action. 然后它只是一个控制问题 - 拖动到适当的行动。

Here is a code sample for UISwipeGestureRecognizer usage. 以下是UISwipeGestureRecognizer用法的代码示例。 Note comments. 注意评论。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //add gesture recognizer. The 'direction' property of UISwipeGestureRecognizer only sets the allowable directions. It does not return to the user the direction that was actaully swiped. Must set up separate gesture recognizers to handle the specific directions for which I want an outcome.
    UISwipeGestureRecognizer *gestureRight;
    UISwipeGestureRecognizer *gestureLeft;
    gestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight:)];//direction is set by default.
    gestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];//need to set direction.
    [gestureLeft setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    //[gesture setNumberOfTouchesRequired:1];//default is 1
    [[self view] addGestureRecognizer:gestureRight];//this gets things rolling.
    [[self view] addGestureRecognizer:gestureLeft];//this gets things rolling.
}

swipeRight and swipeLeft are methods that you use to perform specific activities based on left or right swiping. swipeRight和swipeLeft是用于基于向左或向右滑动执行特定活动的方法。 For example: 例如:

- (void)swipeRight:(UISwipeGestureRecognizer *)gesture
{
    NSLog(@"Right Swipe received.");//Lets you know this method was called by gesture recognizer.
    NSLog(@"Direction is: %i", gesture.direction);//Lets you know the numeric value of the gesture direction for confirmation (1=right).
    //only interested in gesture if gesture state == changed or ended (From Paul Hegarty @ standford U
    if ((gesture.state == UIGestureRecognizerStateChanged) ||
    (gesture.state == UIGestureRecognizerStateEnded)) {

    //do something for a right swipe gesture.
    }
}
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");
        //Left
        //Right
        //Top
        //Bottom
    }

Swift 2.1 斯威夫特2.1

I had to use the following 我不得不使用以下内容

    for var x in [
        UISwipeGestureRecognizerDirection.Left,
        UISwipeGestureRecognizerDirection.Right,
        UISwipeGestureRecognizerDirection.Up,
        UISwipeGestureRecognizerDirection.Down
    ] {
        let r = UISwipeGestureRecognizer(target: self, action: "swipe:")
        r.direction = x
        self.view.addGestureRecognizer(r)
    }

hmm, strange, it works perfect for me, I do exactly same thing 嗯,奇怪,它对我来说很完美,我做的完全一样

think you should try look at 认为你应该试试看

UIGestureRecognizerDelegate method UIGestureRecognizerDelegate方法

- (BOOL)gestureRecognizerShouldBegin:(UISwipeGestureRecognizer *)gestureRecognizer {
   // also try to look what's wrong with gesture
   NSLog(@"should began gesture %@", gestureRecognizer);
   return YES;
}

in logs you must see something like: 在日志中你必须看到类似的东西:

should began gesture ; 应该开始做手势; target= <(action=actionForUpDownSwipeGestureRecognizer:, target=)>; target = <(action = actionForUpDownSwipeGestureRecognizer:,target =)>; direction = up,down,left,right> 方向=上,下,左,右>

use this, it should be the bit operation 使用这个,应该是位操作

   gesture.direction & UISwipeGestureRecognizerDirectionUp || 
   gesture.direction & UISwipeGestureRecognizerDirectionDown

This was driving me crazy. 这让我发疯了。 I finally figured out a reliable way to have multiple swipeGestureRecognizers. 我终于找到了一种可靠的方法来拥有多个swipeGestureRecognizer。

It appears there is a bug in iOS if the name of your "action" selector is the same across multiple swipeGestureRecognizers. 如果“action”选择器的名称在多个swipeGestureRecognizer中相同,则iOS中似乎存在错误。 If you just name them differently, eg handleLeftSwipeFrom and handleRightSwipeFrom, everything works. 如果你只是以不同的名称命名它们,例如handleLeftSwipeFrom和handleRightSwipeFrom,一切正常。

UISwipeGestureRecognizer *recognizer;

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UISwipeGestureRecognizer工作方向错误 - UISwipeGestureRecognizer works in wrong direction UISwipeGestureRecognizer 只有一个方向工作 - UISwipeGestureRecognizer only one direction working UISwipeGestureRecognizer方向(左/右),带有4个子视图 - UISwipeGestureRecognizer Direction (left/Right) with 4 subView 在Interface Builder中更改UISwipeGestureRecognizer方向 - Change UISwipeGestureRecognizer direction in Interface Builder 无法正确获取UISwipeGestureRecognizer方向 - Couldn't get UISwipeGestureRecognizer direction correctly 手动设置初始ViewController后,UISwipeGestureRecognizer无法正常工作 - UISwipeGestureRecognizer not working after setting initial ViewController manually 在设置requireGestureToFail后,将UIPanGestureRecognizer和UISwipeGestureRecognizer添加到同一视图会导致冲突 - Adding a UIPanGestureRecognizer and a UISwipeGestureRecognizer to same view causes conflicts after setting requireGestureToFail 如何识别左/右滑动手势? 比UISwipeGestureRecognizer.direction.right / left更宽松 - How to recognize left/right swipe gestures? More lenient than UISwipeGestureRecognizer.direction.right/left 设置UIMenuController箭头方向不起作用 - Setting UIMenuController arrow direction not working SpriteKit和UISwipeGestureRecognizer - SpriteKit and UISwipeGestureRecognizer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM