UISwipeGestureRecognizer的设置方向


132

我想向基于视图的iPhone项目中添加简单的滑动手势识别。应当识别所有方向(右,下,左,上)的手势。

在UISwipeGestureRecognizer的文档中进行了说明:

您可以通过使用按位或操作数指定多个UISwipeGestureRecognizerDirection常量来指定多个方向。默认方向是UISwipeGestureRecognizerDirectionRight。

但是对我来说这是行不通的。对所有四个方向进行“或”运算后,只能识别左右滑动。

- (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.");
}

我通过在视图中添加四个识别器来解决此问题,但我很想知道为什么它不能像文档中所宣传的那样起作用?

- (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.");
}

3
它是完全无关的,但是[super viewDidLoad]; 应该是-(void)viewDidLoad
Mihir Mehta

Answers:


115

似乎有一个错误。您可以像指定操作一样指定允许的方向。但是,当您尝试访问在操作选择器方法中触发滑动的实际方向时,仍会得到最初设置的位掩码(用于允许的方向)。

这意味着当允许多个方向时,检查实际方向总是会失败。当您在选择器方法(即-(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer)中输出“ direction”的值时,您可以轻松地自己看到它。

向Apple提交了错误报告(#8276386)。

[更新]我从苹果公司得到了一个答复,称该行为按预期进行。

因此,例如,在表格视图中,您可以在表格视图单元格中向左或向右滑动以触发“删除”(这会将滑动手势的方向设置为左右)

这意味着原始的解决方法是应该使用的方法。direction属性只能用于正确识别手势,而不能用于成功识别以比较触发识别的实际方向的方法。


35
我愿意打赌,几乎每个首先使用滑动手势识别器的人都对direction属性的工作原理做出了完全相同的错误假设。
记忆

必须创建4个不同的识别器来跟踪上,下,左和右滑动是很愚蠢的,但是就在这里。
记忆

哇,那还
不错,

2
他们的头文件说:@property(非原子)UISwipeGestureRecognizerDirection方向;//默认值为UISwipeGestureRecognizerDirectionRight。所需的滑动方向。可以指定多个方向
nicktmro 2011年

1
同意这对于Apple而言似乎是一个奇怪的实现。您应该能够指定多个方向,然后测试其中一个方向。
ChrisP

25

我注意到左/右和上/下手势是成对工作的,因此您只需要指定两个手势识别器即可。而且文档似乎确实是错误的。


这是正确的解决方案。2个GR,一个用于上/下/一个用于左和右。答对了!
logancautrell 2011年

22

好了,我添加了两个提到的类似Lars的手势解决了问题,并且效果很好。

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];

13
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];

现在这是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
      }
 }

5

如果使用Xcode 4.2,则可以在情节提要中添加手势识别器@,然后将GUI手势识别器链接到IBAction。

您可以在“实用程序”窗格的“对象库”(“右侧”窗格的底部)中找到“手势识别器”。

然后,只需将控制拖到适当的操作即可。


5

如果要它检测所有四个方向,则需要像在变通方法中那样创建四个实例。

原因:您创建的UISwipeGestureRecognizer实例是作为发送者传递给选择器的实例。因此,如果将其设置为可以识别所有四个方向,则对于sgr.direction == xxxxxx是四个方向中的任何一个方向,它将返回true 。

这是一种涉及较少代码的替代解决方法(假定使用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];
}

2

这是UISwipeGestureRecognizer用法的代码示例。注意注释。

- (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和swipeLeft是用于基于向左或向右滑动执行特定活动的方法。例如:

- (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.
    }
}

2
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
    }

2

斯威夫特2.1

我不得不使用以下

    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)
    }

1

嗯,很奇怪,对我来说很完美,我做的完全一样

认为你应该看看

UIGestureRecognizerDelegate方法

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

在日志中,您必须看到类似以下内容:

应该开始手势; target = <(action = actionForUpDownSwipeGestureRecognizer :, target =)>; 方向=上,下,左,右>


什么不起作用?gestureRecognizerShouldBegin:效果很好。
Danyal Aytekin 2011年

1

使用它,应该是位操作

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

0

这让我发疯。我终于找到了拥有多个swipeGestureRecognizer的可靠方法。

如果您的“动作”选择器的名称在多个swipeGestureRecognizers中相同,则iOS上似乎存在错误。如果只是以不同的方式命名它们,例如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];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.