【问题标题】:Setting direction for UISwipeGestureRecognizer为 UISwipeGestureRecognizer 设置方向
【发布时间】:2010-07-23 14:39:57
【问题描述】:

我想将简单的滑动手势识别添加到基于视图的 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.");
}

【问题讨论】:

  • 完全不相关,但是[super viewDidLoad];应该是 - (void)viewDidLoad 中的第一条语句

标签: ios iphone swipe uiswipegesturerecognizer


【解决方案1】:

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

这意味着当允许超过 1 个方向时,对实际方向的检查总是会失败。 当你在选择器方法中输出'direction'的值(即-(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer)时,你可以很容易地看到它。

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

[更新] 我得到了 Apple 的答复,说该行为按预期工作。

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

这意味着最初的解决方法是它应该使用的方式。 direction 属性只能用于正确识别手势,但不能在成功识别时执行的方法中用于比较触发识别的实际方向。

【讨论】:

  • 我敢打赌,几乎每个第一次使用滑动手势识别器的人都会对方向属性的工作方式做出完全相同的错误假设。
  • 必须创建 4 个不同的识别器来跟踪向上、向下、向左和向右滑动,这很愚蠢,但你就是这样。
  • 哇,这有点糟糕,不是什么大不了的事,但似乎他们可以添加一些东西
  • 他们的头文件说:@property(nonatomic) UISwipeGestureRecognizerDirection 方向; // 默认是 UISwipeGestureRecognizerDirectionRight。所需的滑动方向。可以指定多个方向
  • 同意这对 Apple 来说似乎是一个奇怪的实现。您应该能够指定多个方向,然后测试其中一个方向。
【解决方案2】:

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

【讨论】:

  • 这是正确的解决方案。 2个GRs,一个用于上下/一个用于左右。宾果游戏!
【解决方案3】:

这很糟糕,我通过添加像 Lars 提到的 2 个手势解决了这个问题,并且效果很好......

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

【讨论】:

    【解决方案4】:
    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 手势识别器链接到 IBActions。

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

      然后它只是控制拖动到适当的动作的问题。

      【讨论】:

        【解决方案6】:

        如果您希望它检测所有四个方向,则需要创建四个实例,就像您在解决方法中所做的那样。

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

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

        【讨论】:

          【解决方案7】:

          斯威夫特 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)
              }
          

          【讨论】:

            【解决方案8】:

            这是 UISwipeGestureRecognizer 使用的代码示例。注意 cmets。

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

            【讨论】:

              【解决方案9】:
              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
                  }
              

              【讨论】:

                【解决方案10】:

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

                觉得你应该试试看

                UIGestureRecognizerDelegate 方法

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

                在日志中,您必须看到如下内容:

                应该开始手势;目标=;方向 = 上、下、左、右>

                【讨论】:

                • 什么不起作用?手势识别器应该开始:工作正常。
                【解决方案11】:

                用这个,应该是位操作

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

                【讨论】:

                  【解决方案12】:

                  这让我发疯了。我终于想出了一个可靠的方法来拥有多个 swipeGestureRecognizers。

                  如果您的“动作”选择器的名称在多个 swipeGestureRecognizer 中相同,则 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];
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-04-17
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-10-08
                    • 2017-02-11
                    • 2014-12-10
                    相关资源
                    最近更新 更多